ala*_*oot 8 python inheritance super python-3.x
python 中内置函数的一个用例super()是调用重写的方法。super()这是一个使用调用Parent类函数的简单示例echo:
class Parent():
def echo(self):
print("in Parent")
class Child(Parent):
def echo(self):
super().echo()
print("in Child")
Run Code Online (Sandbox Code Playgroud)
我见过将 2 个参数传递给super(). 在这种情况下,签名看起来有点像子类从super(subClass, instance)哪里调用,并且是调用的实例,即。因此,在上面的示例中,该行将变为:subClasssuper()instanceselfsuper()
super(Child, self).echo()
Run Code Online (Sandbox Code Playgroud)
查看python3 文档,从类内部调用时,这两个用例是相同的。
super()从 python3 开始,使用 2 个参数的调用是否已完全弃用?如果这仅在调用重写函数时被弃用,您能否举例说明为什么其他情况需要它们?
我也有兴趣知道为什么 python 需要这两个参数?在 python3 中进行调用时是否会注入/评估它们super(),或者在这种情况下不需要它们?
Sha*_*ger 10
如果您不传递参数,Python 3 会尽力为您提供它们。这有点笨拙,但通常有效。本质上,它只是假设方法的第一个参数是self( 的第二个参数super),并且当类定义完成时,它为引用super或__class__定义__class__为您刚刚定义的类的任何函数提供虚拟闭包范围,因此不需要-argsuper()可以检查堆栈帧以查找__class__作为第一个参数。
这通常有效,但也有无效的情况:
在staticmethods 中(因为第一个参数实际上不是类),尽管staticmethods 并不真正应该以相同的方式参与继承层次结构,所以这并不完全出乎意料。
在作为*args第一个参数的函数中(这是实现任何接受任意关键字参数的方法的唯一安全方法,例如dict3.8 之前的子类,当它们引入仅位置参数时)。
如果super调用位于嵌套作用域中,则该作用域可以是隐式的,例如生成器表达式或任何类型的理解(list、set、dict),因为嵌套作用域不直接附加到类,因此它不会获得__class__定义附加到类本身的方法所具有的魔力。
在极少数情况下,您可能希望显式绕过特定类来解析父方法,在这种情况下,您需要在 MRO 中显式传递一个与默认情况下拉取的类不同的类。这是深奥而可怕的魔法,所以我不推荐它,但我想我有理由这样做一次。
所有这些都是相对罕见的情况,因此大多数时候,对于纯粹针对 Python 3 的代码,您可以使用 no-arg ,并且只有当您出于某种原因无法super使用它时才回退到显式传递参数。无参数super更干净、更快,并且在实时开发过程中可以更正确(如果替换MyClass,旧版本类的实例将缓存旧版本,无参数super将继续工作,手动查找你的全局变量会找到该类的新版本并爆炸),所以只要有可能就使用它。