【发布时间】:2016-12-15 21:48:46
【问题描述】:
考虑以下示例代码:
from abc import ABC, abstractmethod, abstractproperty
class Base(ABC):
@abstractmethod
def foo(self) -> str:
print("abstract")
@property
@abstractmethod
def __name__(self) -> str:
return "abstract"
@abstractmethod
def __str__(self) -> str:
return "abstract"
@property
@abstractmethod
def __add__(self, other) -> str:
return "abstract"
class Sub(Base):
def foo(self):
print("concrete")
def __str__(self):
return "concrete"
def __add__(self, other) -> str:
return "concrete"
sub = Sub()
sub.foo()
sub.__name__
print(str(sub))
请注意,子类没有实现抽象属性__name__,实际上,当引用__name__ 时,它会从其父类打印为“抽象”:
>>> sub.foo()
concrete
>>> sub.__name__
'abstract'
>>> print(str(sub))
concrete
然而,这并不是因为__name__ 是一个笨拙的方法,也不是因为@property 和@abstractmethod 装饰器不能很好地协同工作,因为如果我从Sub 中删除__add__ 的实现,它不允许我实例化它。 (我知道__add__ 通常不是属性,但我想使用“真正的”dunder 方法)如果我删除__str__ 和foo 的实现,也会出现同样的预期行为。只有__name__ 有这种行为。
__name__ 是什么导致了这种行为?有什么办法可以解决这个问题,还是我需要让父(抽象)实现为我手动提升TypeError?
【问题讨论】:
标签: python abstract-class python-3.5 abc