当在派生类中调用super()时,我可以传入self .__ class__吗?
我最近发现(通过StackOverflow),要调用基类中的方法,我应该调用:
super([[derived class]], self).[[base class method]]()
这很好,它工作。 然而,当我做出改变时,我发现自己经常在类之间复制和粘贴,并且经常忘记修改派生类参数到super()函数。
我想避免不得不记得改变派生类的参数。 我可以改为使用self.__class__
作为super()函数的第一个参数吗?
这似乎工作,但有没有很好的理由,为什么我不应该这样做?
你不能。 super()
调用需要知道该方法是什么类的一部分,以search基类重写的方法。
如果你传入self.__class__
(或者更好的是, type(self)
),那么super()
被赋予错误的起点来search方法,并且最终会再次调用它自己的方法 。
将其看作构成方法parsing顺序序列的类列表中的一个指针。 如果你传入type(self)
那么指针将引用任何子类而不是原始的起始点。
下面的代码导致无限的recursion错误:
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
因为在Derived.method()
type(self)
是Subclass
, 而不是 Derived
。
在这个例子中, Subclass
的MRO是[Subclass, Derived, Base]
,而super()
需要知道从哪里开始search任何重写的方法。 通过使用type(self)
你告诉它从Subclass
开始,所以它会在下一个findDerived.method()
,这是我们开始的地方。
self.__class__
可能不是一个子类,而是一个孙辈或更年轻的类,从而导致一个堆栈中断循环。