Python 3.6:abc.abstracmethod class 方法未检查 class 级别调用
Python 3.6: abc.abstracmethod on classmethod no check on class level call
With python 3.6,当我用具有 metaclass=abc.ABCMeta
的 class 用 abc.abstractmethod
装饰 abstractmehod
时,抽象方法可以从class(不是实例)观点。
似乎 abc
装饰器在实例化 class 时执行检查,因此从实例调用时没有完成。
这种行为非常令人不安,看起来像是 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
此行为与 @classmethod
的文档中描述的行为一致。
https://docs.python.org/3.6/library/functions.html?highlight=classmethod#classmethod
"It can be called either on the class (such as C.f()) or on an instance (such as C().f())."
在这种情况下,它不能在实例上调用,因为它是抽象的,但由于它是一个class方法,直接在class上调用它还是可以的。
With python 3.6,当我用具有 metaclass=abc.ABCMeta
的 class 用 abc.abstractmethod
装饰 abstractmehod
时,抽象方法可以从class(不是实例)观点。
似乎 abc
装饰器在实例化 class 时执行检查,因此从实例调用时没有完成。
这种行为非常令人不安,看起来像是 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
此行为与 @classmethod
的文档中描述的行为一致。
https://docs.python.org/3.6/library/functions.html?highlight=classmethod#classmethod
"It can be called either on the class (such as C.f()) or on an instance (such as C().f())."
在这种情况下,它不能在实例上调用,因为它是抽象的,但由于它是一个class方法,直接在class上调用它还是可以的。