如果你希望在子类中调用超类的抽象方法时出现错误,则需要手动引发异常。(即使它能够直接与类一起工作,也需要创建一个 Exception 类的实例,并在 raise 命令中使用 NotImplementedError()。)
然而,现有的行为实际上非常方便:如果你的抽象方法只包含 pass,则可以有任意数量的子类继承基类,并且只要至少一个实现抽象方法,它就会起作用。即使它们全部调用 super() 等效方法而没有检查其他任何内容。
如果在复杂层次结构中(例如,使用 mixins 等),会调用错误(NotImplementedError 或其他错误),则每次调用 super 时都需要检查是否已引发错误,以便跳过它。值得一提的是,可以使用条件检查 super() 是否会与其中方法是抽象的类相遇。
if not getattr(super().foo, "__isabstractmethod__", False):
super().foo(...)
既然你希望当你达到方法层次结构的基础时,它什么都不做,那么如果什么也不发生,那就更简单了!
我的意思是,看看这个:
class A(abc.ABC):
@abstractmethod
def validate(self, **kwargs):
pass
class B(A):
def validate(self, *, first_arg_for_B, second_arg_for_B=None, **kwargs):
super().validate(**kwargs)
...
class C(A)
def validate(self, *, first_arg_for_C **kwargs):
super().validate(**kwargs)
...
class Final(B, C):
...
B.validate
和
C.validate
都不需要担心层次结构中的其他类,只需执行它们自己的操作并传递即可。
如果
A.validate
引发异常,则两个方法都必须在
try: ...; except ...: pass
语句内执行
super().validate(...)
,或者在奇怪的
if
块内执行,这样做没有任何好处。
更新 - 我刚在官方文档中找到了这个注释:
注意 与Java抽象方法不同,这些抽象方法可以有实现。该实现可以通过覆盖它的类中的super()机制调用。在使用协作多重继承的框架中,这可能对于超级调用的终点非常有用。
https://docs.python.org/3/library/abc.html#abc.abstractmethod
如果您能在评论中回复,我甚至会向您提出一个个人问题:我知道在Java中这不是很相关,因为不能有多重继承,因此即使在大的继承体系中,第一个子类实现抽象方法通常也会被广泛知晓。但是,在Java项目中,如果可以选择各种基本具体类,并以任意顺序进行其他操作,那么由于抽象方法的提出,该如何解决?