我试图弄清楚如何确保使用适当的装饰器创建从 ABC 继承的类的方法。我(希望)了解 ABC 的一般工作原理。
from abc import ABCMeta, abstractmethod
class MyABC(metaclass=ABCMeta):
@abstractmethod
def my_abstract_method(self):
pass
class MyClass(MyABC):
pass
MyClass()
这给出了“TypeError:无法使用抽象方法 my_abstract_method 实例化抽象类 MyClass”。太好了,有道理。只需创建一个具有该名称的方法即可。
class MyClass(MyABC):
def my_abstract_method(self):
pass
MyClass()
繁荣。你完成了。但是这个案例呢?
from abc import ABCMeta, abstractmethod
class MyABC(metaclass=ABCMeta):
@property
@abstractmethod
def my_attribute(self):
pass
class MyClass(MyABC):
def my_attribute(self):
pass
MyClass()
即使 my_attribute 不是属性,MyClass() 调用也可以工作。我想最终所有 ABC 所做的就是确保具有给定名称的方法存在。就是这样。如果你想了解更多,你必须查看 MyABC 的源代码并阅读文档。那里的装饰器和注释将告诉您需要如何构造子类。
我说得对还是我在这里遗漏了什么?
最佳答案
你说得对,ABC 并不强制执行这一点。没有办法强制执行“具有特定装饰器”之类的内容。装饰器只是返回对象的函数(例如,property 返回属性对象)。 ABCMeta 不做任何事情来确保类上定义的属性是任何特定的;它只是确保它们在那里。这“有效”,没有错误:
class MyABC(metaclass=ABCMeta):
@abstractmethod
def my_abstract_method(self):
pass
class MyClass(MyABC):
my_abstract_method = 2
MyClass()
也就是说,ABCMeta 甚至不确保子类上提供的抽象方法根本就是一个方法。必须有某种具有该名称的属性,
您当然可以编写自己的元类来进行更复杂的检查,以确保某些属性具有某些类型的值,但这超出了 ABCMeta 的范围。
关于python - ABC 强制方法装饰器吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38840771/