在派生类中调用super()时,可以传递self .__ class__吗?
我最近发现,在我应该调用的基类中调用方法:
super([[derived class]], self).[[base class method]]()
很好,可以。但是,我发现自己经常在类之间进行复制和粘贴,而常常忘记将派生类参数固定为super()函数。
我想避免必须记住要更改派生类参数。我是否可以仅将其self.__class__
用作super()函数的第一个参数?
它似乎可行,但是有充分的理由为什么我不应该这样做?
-
你不能。该
super()
调用需要知道该方法属于哪个类,以在基类中搜索被覆盖的方法。如果您在传递
self.__class__
(或更好,type(self)
)则super()
给出 错误的 出发点,以寻找方法,并最终调用_再次它自己的方法_ 。在构成方法解析顺序序列的类列表中,将其视为指针。如果传入,
type(self)
则指针将引用任何子类,而不是原始起点。以下代码导致无限递归错误:
class Base(object): def method(self): print 'original' class Derived(Base): def method(self): print 'derived' super(type(self), self).method() class Subclass(Derived): def method(self): print 'subclass of derived' super(Subclass, self).method()
演示:
>>> Subclass().method() subclass of derived derived derived derived <... *many* lines removed ...> File "<stdin>", line 4, in method File "<stdin>", line 4, in method File "<stdin>", line 4, in method RuntimeError: maximum recursion depth exceeded while calling a Python object
因为
type(self)
是Subclass
, 没有Derived
在Derived.method()
。在这个例子中,MRO为
Subclass
是[Subclass, Derived, Base]
,而super()
需要知道从哪里开始寻找任何替代的方法。通过使用type(self)
它告诉它从开始Subclass
,所以它将Derived.method()
在我们开始的地方找到下一个。