我最近发现,在我应该调用的基类中调用方法:
super([[derived class]], self).[[base class method]]()
很好,可以。但是,我发现自己经常在类之间进行复制和粘贴,而常常忘记将派生类参数固定为super()函数。
我想避免必须记住要更改派生类参数。我是否可以仅将其self.__class__用作super()函数的第一个参数?
self.__class__
它似乎可行,但是有充分的理由为什么我不应该这样做?
你不能。该super()调用需要知道该方法属于哪个类,以在基类中搜索被覆盖的方法。
super()
如果您在传递self.__class__(或更好,type(self))则super()给出 错误的 出发点,以寻找方法,并最终调用_再次它自己的方法_ 。
type(self)
在构成方法解析顺序序列的类列表中,将其视为指针。如果传入,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()。
Subclass
Derived
Derived.method()
在这个例子中,MRO为Subclass是[Subclass, Derived, Base],而super()需要知道从哪里开始寻找任何替代的方法。通过使用type(self)它告诉它从开始Subclass,所以它将Derived.method()在我们开始的地方找到下一个。
[Subclass, Derived, Base]