ABCs是否强制执行方法装饰器?

时间:2016-08-09 01:41:07

标签: python decorator abc

我试图找出如何确保使用适当的装饰器创建从ABC继承的类的方法。我(希望)了解ABCs的工作原理。

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()调用仍然有效。我想最终所有ABCs都确保存在具有给定名称的方法。而已。如果您想从中获得更多,您必须查看MyABC的源代码并阅读文档。那里的装饰器和注释将告诉您如何构建子类。

我是否正确或我在这里遗漏了什么?

1 个答案:

答案 0 :(得分:1)

你是正确的,ABCs不强制执行。没有办法强制执行“有一个特定的装饰者”之类的东西。装饰器只是返回对象的函数(例如,property返回一个属性对象)。 ABCMeta没有做任何事情来确保类中定义的属性是特别的;它只是确保他们在那里。这“无效”:

class MyABC(metaclass=ABCMeta):
    @abstractmethod
    def my_abstract_method(self):
        pass

class MyClass(MyABC):
    my_abstract_method = 2

MyClass()

也就是说,ABCMeta甚至不确保子类提供的抽象方法是一个方法。只需要有一个具有该名称的属性,

你当然可以编写自己的元类来进行更复杂的检查,以确保某些属性具有某些类型的值,但这超出了ABCMeta的范围。