Pie*_*esi 8 python inheritance abstract-class abc python-decorators
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()
Run Code Online (Sandbox Code Playgroud)
但是,如果我让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()
Run Code Online (Sandbox Code Playgroud)
我发现即使在更复杂的架构上也是如此,所以我想知道:后一种方法什么时候会失败?
您看不到任何区别,因为您的第一个子类确实实现了do_something
抽象方法。
注释掉两个版本中子类中的定义do_something
,您会发现在第一种情况下,TypeError
当尝试实例化子类时,您会得到一个 - 您还会得到一个尝试实例化第一个版本Base
类本身的FWIW。在第二个版本中,您可以实例化这两个类(这应该是不可能的,因为它们是抽象的)并调用抽象do_something
方法 - 这违背了 ABC 的要点之一。
您还会错过 ABC FWIW 的许多其他有趣功能......
归档时间: |
|
查看次数: |
2138 次 |
最近记录: |