我注意到带有
abstractmethod
的类如果不继承自ABC
,仍然可以被实例化。这似乎与documentation:
使用这个装饰器需要类的元类是 ABCMeta 或派生自它。除非重写其所有抽象方法和属性,否则无法实例化具有从 ABCMeta 派生的元类的类。
由此我会明白
@abstractmethod
作为元类,则将
ABCMeta
我起草了以下示例:
from abc import abstractmethod, ABC
class TestClassOne:
@abstractmethod
def test_method(self):
...
class TestClassTwo(ABC):
@abstractmethod
def test_method(self):
...
test_object_one = TestClassOne()
test_object_two = TestClassTwo()
在 Python 3.9.13 或 3.11.3 上运行给出输出
TypeError: 无法使用抽象方法 test_method 实例化抽象类 TestClassTwo
但值得注意的是这个错误没有提到
TestClassOne
.
我是不是误解了什么,或者这可能是 Python 中的错误?
ABCMeta
元类和 @abstractmethod
装饰器一起工作以防止实例化未实现所需方法的类。没有另一个,它们中的每一个都没有效果。
因此,如果您定义一个没有任何
@abstractmethod
装饰器的抽象基类,它允许实例化——它不是 真正 抽象。
如果你在非 ABC 中使用
@abstractmethod
,它会被忽略,因为它是实际实现强制执行的元类。这个装饰器简单地将方法注册为需要在子类中重写。