我正在尝试理解何时以及如何在Python中正确使用super() ( 2.7.x或3.x)。
在>>> help(super)上,解释器告诉我如何调用它:
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(obj) (),但我不明白为什么不能使用super()。或类定义中的super(self)。
我知道这肯定是有原因的,但我找不到。对我来说,这些代码行相当于super(obj.__class__, obj)或super(self.__class__, self),它们可以正常工作吗?
我认为,即使在Python3.x中,只输入super(obj)也是一个很好的捷径。
发布于 2013-07-07 14:53:17
双参数形式只在Python2中需要。原因是self.__class__总是引用继承树中的“叶”类--也就是对象的最具体的类--但是当您调用super时,您需要告诉它当前正在调用哪个实现,以便它可以调用继承树中的下一个实现。
假设你有:
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()会发生什么。
当您在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,并发生无限递归。
当然,您真正想要的是能够调用super(classThatDefinedTheImplementationThatIsCurrentlyExecuting, self),这实际上就是Python3 super()所做的。
在Python3中,你可以只做super().foo(),它会做正确的事情。我不清楚你说super(self)是一条捷径是什么意思。在Python2中,由于我上面描述的原因,它不能工作。在Python3中,它将是一个“长切换”,因为你可以直接使用普通的super()。
在Python3中,偶尔可能仍然需要使用super(type)和super(type1, type2),但对于不寻常的情况,这些用法总是更加深奥。
发布于 2017-04-03 19:39:07
尝试简短的回答:
self.__class__始终是对象实例的实际(“次最”)类-不一定是实现函数的所需类!
将super(self.__class__, self)替换为super(__class__, self),您就进入了Python3中的方法定义,因为Python3为实现类提供了魔术单元变量__class__。
在Python3中,不带参数的简单super()已经是super(__class__, self)的快捷方式了。请参阅PEP3135。
Python2既不知道__class__,也不知道零参数快捷方式super()。
https://stackoverflow.com/questions/17509846
复制相似问题