Python super()参数:为什么不是super(obj)?

2024-06-28 20:25:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图了解何时以及如何在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(),但我不明白为什么super(obj)是不可能的。或类定义中的super(self)

我知道一定有原因,但我找不到。对我来说,这些线相当于super(obj.__class__, obj)super(self.__class__, self),它们能正常工作吗?

我认为,即使在Python 3.x中输入super(obj)也是一个不错的快捷方式


Tags: selfobj定义objecttypehelp解释器class
2条回答

只有在Python 2中才需要双参数形式。原因是self.__class__总是引用继承树中的“leaf”类——也就是对象的最特定类——但是当您调用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),这实际上就是Python 3super()所做的。

在Python 3中,您可以只做super().foo(),它会做正确的事情。我不清楚你说的super(self)是一条捷径是什么意思。在Python 2中,由于我上面描述的原因,它不能工作。在Python 3中,它将是一个“longcut”,因为您只需使用纯super()即可。

Python 3中偶尔仍需要使用super(type)super(type1, type2),但对于不寻常的情况,这些用法通常更为深奥。

尝试一个简短的答案:

self.__class__始终是对象实例的实际(“次最”)类,不一定是实现函数的所需类!

super(__class__, self)替换super(self.__class__, self),您就在Python 3中的方法定义中,因为python3为实现类提供了magic cell变量__class__

简单的super()零参数已经是Python 3中super(__class__, self)的快捷方式。见PEP3135

Python 2既不知道__class__,也不知道零参数快捷方式super()

相关问题 更多 >