【问题标题】:Do ABCs enforce method decorators?ABC 是否强制执行方法装饰器?
【发布时间】:2016-12-14 21:52:20
【问题描述】:

我试图弄清楚如何确保使用适当的装饰器创建从 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 的源代码并阅读文档。那里的装饰器和 cmets 会告知您需要如何构建子类。

我说得对还是我在这里遗漏了什么?

【问题讨论】:

  • 这就是abstractproperty 的用途。
  • abstractproperty 在 python 3.3 中已弃用。 OP 对 3.3+ 有正确用法; @property@abstractmethod 在基类中,@property 在子类中。但是,您不能强制子类正确实现它。

标签: python decorator abc


【解决方案1】:

你说得对,ABC 不会强制执行这一点。没有办法强制执行诸如“具有特定装饰器”之类的内容。装饰器只是返回对象的函数(例如,property 返回一个属性对象)。 ABCMeta 没有做任何事情来确保类上定义的属性是特定的;它只是确保它们在那里。这个“工作”没有错误:

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

class MyClass(MyABC):
    my_abstract_method = 2

MyClass()

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

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

【讨论】:

  • 谢谢。我认为 ABC 能够准确地检查特定的装饰器,因为它们返回类实例(取决于它们的定义方式)。似乎 isinstance() 可以用来在那里进行检查。都很好。我试图想办法让我的“静态类型”粉丝同事开心。我读到 ABC 可用于强制执行接口,但似乎并非如此。
  • @VagueAdvice:我对装饰器的看法是,您只能强制执行属性具有的值类型,而不是该值是通过装饰器还是通过其他方式创建的。 (但无论如何,你不能用 ABC 来做到这一点。)如果你想满足静态类型的粉丝,你可能想看看新的 typing 模块。
  • 我明白了。感谢typing 的提示。我在开玩笑说那些家伙是粉丝。显然静态类型有很大的好处。我们正在考虑改变这里的堆栈,我想推动 python。他们提出这是一个巨大的弱点。我只是想看看外面有什么,然后遇到了 ABC。使用 mypy 作为 linter 的类型提示(以及 IDE 警告)可能有助于解决问题。
猜你喜欢
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
  • 2018-12-13
  • 2015-10-23
  • 2023-01-04
  • 2012-04-05
  • 2011-09-28
相关资源
最近更新 更多