首页 > 解决方案 > Python 3.6:classmethod 上的 abc.abstracmethod 不检查类级别调用

问题描述

使用python 3.6,当我用一个类来装饰一个abstractmehod具有的类时,可以从类(而不是实例)的角度调用抽象方法。abc.abstractmethodmetaclass=abc.ABCMeta

当类被实例化时,装饰器似乎abc正在执行检查,所以从实例调用时没有完成。

这种行为非常令人不安,它看起来像是abc模块中的一个错误。

我错过了什么?

谢谢

代码示例:

import abc
import sys

class P(metaclass=abc.ABCMeta):
    @classmethod
    @abc.abstractmethod
    def acm(cls):
        pass

class X(P):
    pass

print("P.acm()", file=sys.stderr)
try:
    P.acm()
    print("OK")
except Exception as e:
    print(f"KO: {e}")

print("P().acm()", file=sys.stderr)
try:
    P().acm()
    print("OK")
except Exception as e:
    print(f"KO: {e}")

结果:

P.acm()
OK
P().acm()
KO: Can't instantiate abstract class P with abstract methods acm

标签: pythonabstract-classclass-methodabstract-methods

解决方案


此行为与文档中描述的行为一致@classmethod

https://docs.python.org/3.6/library/functions.html?highlight=classmethod#classmethod

“它可以在类(例如 Cf())或实例(例如 C().f())上调用。”

在这种情况下,它不能在实例上调用,因为它是抽象的,但由于它是一个类方法,所以直接在类上调用它还是可以的。


推荐阅读