如果我用抽象方法定义一个抽象类:
import abc
class A(abc.ABC):
@classmethod
@abc.abstractmethod
def foo(cls):
pass
我无法实例化它(如预期的那样):
>>> A()
TypeError: Can't instantiate abstract class A with abstract methods foo
但是我可以毫无错误地调用它的抽象方法。
>> A.foo()
是否在某处记录了此行为?
在 Python 3.6 和 3.7 上测试。
请您参考如下方法:
对此没有任何明确的规定。
只是 abstractmethod 装饰器的文档说:
A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and properties are overridden.
PEP 3119 说:
A class containing at least one method declared with this decorator that hasn't been overridden yet cannot be instantiated.
以后
Implementation: The
@abstractmethoddecorator sets the function attribute__isabstractmethod__to the value True. TheABCMeta.__new__method computes the type attribute__abstractmethods__as the set of all method names that have an__isabstractmethod__attribute whose value is true. It does this by combining the__abstractmethods__attributes of the base classes, adding the names of all methods in the new class dict that have a true__isabstractmethod__attribute, and removing the names of all methods in the new class dict that don't have a true__isabstractmethod__attribute. If the resulting__abstractmethods__set is non-empty, the class is considered abstract, and attempts to instantiate it will raiseTypeError.
我对实现部分的解释是,@abstractmethod 从不阻止方法被调用,而只是说该类不能被实例化,子类仍然是抽象的,除非它覆盖了它的所有方法抽象方法。
所以我不会说它是设计的,但它至少是一种假定的副作用。
