PEP 3119指出:
所述
@abstractmethod
装饰应仅在类体中使用,并且仅用于一个其元类是(衍生自)ABCMeta
。不支持将动态方法添加到类,或在创建方法或类后尝试修改其抽象状态。
但是,我找不到为什么的解释。具体来说,仅@abstractmethod
在未明确继承自的类中使用时,我没有注意到行为上的差异ABCMeta
。在下面的简单示例中,如果我理解正确,则正确的处理方式将是:
import six
from abc import ABCMeta
from abc import abstractmethod
class Base(six.with_metaclass(ABCMeta)):
def __init__(self):
print('Init abstract base')
@abstractmethod
def do_something(self):
pass
class Subclass(Base):
def __init__(self):
super(Subclass, self).__init__()
def do_something(self):
print('Done.')
sub = Subclass()
sub.do_something()
但是,如果我让Base
类object
仅从继承,并且仅在需要时使用装饰器,则我注意到行为没有变化。
from abc import abstractmethod
class Base(object):
def __init__(self):
print('Init abstract base')
@abstractmethod
def do_something(self):
pass
class Subclass(Base):
def __init__(self):
super(Subclass, self).__init__()
def do_something(self):
print('Done.')
sub = Subclass()
sub.do_something()
我发现即使在更复杂的体系结构上也是如此,所以我想知道:后一种方法何时会失败?
您没有看到任何区别,因为您的第一个子类确实实现了do_something
abstractmethod。
注释掉这do_something
两个版本中子类的定义,您会发现在第一种情况下TypeError
尝试实例化子类时会得到一个-您还将尝试实例化第一个版本Base
类本身的FWIW。在第二个版本中,您可以实例化这两个类(因为它们是抽象的,所以不可能),然后调用abstractdo_something
方法-破坏了ABC的要点之一。
您还将错过ABC FWIW的许多其他有趣功能...
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句