考虑以下示例代码:
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))
请注意,子类没有实现 abstract 属性__name__
,实际上,当__name__
被引用时,它会从其父类打印为“抽象”:
>>> sub.foo()
concrete
>>> sub.__name__
'abstract'
>>> print(str(sub))
concrete
然而,这不是因为__name__
是一个 dunder 方法,也不是因为@property
和@abstractmethod
装饰器不能很好地协同工作,因为如果我删除__add__
from的实现Sub
,它不会让我实例化它。(我知道__add__
通常不是属性,但我想使用“真正的” dunder 方法)如果我删除 and 的实现,也会发生相同的预期__str__
行为foo
。只能__name__
以这种方式行事。
是什么__name__
导致了这种行为?有没有办法解决这个问题,还是我需要让父(抽象)实现手动TypeError
为我提出?