Python super() 参数:为什么不是 super(obj)?
我试图了解何时以及如何在 Python 中正确使用 super()(2.7.x 或 3.x)
I am trying to understand when and how to use super() in Python correctly (either 2.7.x or 3.x)
关于>>>help(super) 解释器告诉我如何调用它:
on >>> help(super)
the interpreter tells me how to call it:
class super(object)
| super(type) -> unbound super object
| super(type, obj) -> bound super object; requires isinstance(obj, type)
| super(type, type2) -> bound super object; requires issubclass(type2, type)
我知道在 Python3.x 中现在可以在类定义中使用 super(),但我不明白为什么 super(obj)
是不可能的.或 super(self)
在类定义中.
I understand that in Python3.x it's now possible to juse use super() within a class definition, but I don't understand why super(obj)
is not possible. Or super(self)
within a class definition.
我知道一定有原因,但我找不到.对我来说,这些行相当于 super(obj.__class__, obj)
或 super(self.__class__, self)
那些行吗?
I know there must be a reason for it, but I can't find it. To me those lines are equivalent to super(obj.__class__, obj)
or super(self.__class__, self)
and those would work right?
我认为即使在 Python 3.x 中,只要输入 super(obj)
也是一个不错的快捷方式.
I would think that just typing super(obj)
would be a nice shortcut even in Python 3.x.
双参数形式只在 Python 2 中需要.原因是 self.__class__
总是指叶子"继承树中的类——也就是对象最具体的类——但是当你调用 super
时你需要告诉它当前正在调用哪个实现,以便它可以调用下一个在继承树中.
The two-argument form is only needed in Python 2. The reason is that self.__class__
always refers to the "leaf" class in the inheritance tree -- that is, the most specific class of the object -- but when you call super
you need to tell it which implementation is currently being invoked, so it can invoke the next one in the inheritance tree.
假设你有:
class A(object):
def foo(self):
pass
class B(A):
def foo(self):
super(self.__class__, self).foo()
class C(B):
def foo(self):
super(self.__class__, self).foo()
c = C()
请注意,c.__class__
始终是 C
.现在想想如果你调用 c.foo()
会发生什么.
Note that c.__class__
is C
, always. Now think about what happens if you call c.foo()
.
当你在 C 的方法中调用 super(self.__class__, self)
时,就像调用 super(C, self)
,意思是调用由 C 继承的此方法的版本".这将调用 B.foo
,这很好.但是当你从B调用super(self.__class__, self)
时,还是像调用了super(C, self)
,因为是同一个self
,所以 self.__class__
仍然是 C
.结果是 B 中的调用将再次调用 B.foo
并发生无限递归.
When you call super(self.__class__, self)
in a method of C, it will be like calling super(C, self)
, which means "call the version of this method inherited by C". That will call B.foo
, which is fine. But when you call super(self.__class__, self)
from B, it's still like calling super(C, self)
, because it's the same self
, so self.__class__
is still C
. The result is that the call in B will again call B.foo
and an infinite recursion occurs.
当然,您真正想要的是能够调用super(classThatDefinedTheImplementationThatIsCurrentlyExecuting, self)
,而这实际上是Python 3 super()
所做的.
Of course, what you really want is to be able to call super(classThatDefinedTheImplementationThatIsCurrentlyExecuting, self)
, and that is effectively what the Python 3 super()
does.
在 Python 3 中,你可以只做 super().foo()
并且它做正确的事情.我不清楚你所说的 super(self)
作为快捷方式是什么意思.在 Python 2 中,由于我上面描述的原因,它不起作用.在 Python 3 中,这将是一个长切",因为您可以使用普通的 super()
代替.
In Python 3, you can just do super().foo()
and it does the right thing. It's not clear to me what you mean about super(self)
being a shortcut. In Python 2, it doesn't work for the reason I described above. In Python 3, it would be a "longcut" because you can just use plain super()
instead.
super(type)
和 super(type1, type2)
在 Python 3 中可能偶尔仍然需要使用,但对于异常情况,这些用法总是更深奥的用法.
The super(type)
and super(type1, type2)
uses might still be needed occasionally in Python 3, but those were always more esoteric usages for unusual situations.