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上调用它还是可以的。