Python super()参数:为什么不选择super(obj)? [英] Python super() arguments: why not super(obj)?

查看:101
本文介绍了Python super()参数:为什么不选择super(obj)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解何时以及如何在Python(2.7.x或3.x)中正确使用super()

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中,这将是"longcut",因为您可以直接使用普通的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.

在Python 3中偶尔仍然需要super(type)super(type1, type2)用法,但是对于异常情况,这些用法总是更加深奥.

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.

这篇关于Python super()参数:为什么不选择super(obj)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆