什么时候需要将参数传递给 python super()?
When do you need to pass arguments to python super()?
python 中内置的 super()
的一个用例是调用重写的方法。下面是使用 super()
调用 Parent
class 的 echo
函数的简单示例:
class Parent():
def echo(self):
print("in Parent")
class Child(Parent):
def echo(self):
super().echo()
print("in Child")
我见过将 2 个参数传递给 super()
的代码。在那种情况下,签名看起来像 super(subClass, instance)
,其中 subClass
是调用 super()
的子 class,而 instance
是调用的实例,即self
。所以在上面的例子中,super()
行会变成:
super(Child, self).echo()
查看 python3 docs,这两个用例在从 class 内部调用时是相同的。
从 python3 开始,使用 2 个参数调用 super()
是否已完全弃用?如果这只是因为调用重写函数而被弃用,你能举个例子说明为什么其他情况需要它们吗?
我也想知道为什么 python 需要这两个参数?在 python3 中进行 super()
调用时,它们是 injected/evaluated,还是在那种情况下不需要它们?
如果您不传递参数,Python 3 会努力为您提供参数。这有点笨拙,但通常 有效。本质上,它只是假设你的方法的第一个参数是 self
(super
的第二个参数),当 class 定义完成时,它为任何函数提供一个虚拟闭包范围引用 super
或 __class__
将 __class__
定义为您刚刚定义的 class,因此无参数 super()
可以检查堆栈帧以找到 __class__
作为第一个参数。
这通常有效,但在某些情况下无效:
在 staticmethod
s 中(因为第一个参数实际上不是 class),尽管 staticmethod
s 不应该真正参与继承层次结构相同,所以这并不完全出乎意料。
在以 *args
作为第一个参数的函数中(这是实现任何接受任意关键字参数的方法的唯一安全方法,例如 dict
subclasses 在 3.8 之前,当他们引入了仅位置参数时)。
如果 super
调用在嵌套范围内,这可以是隐式的,例如生成器表达式,或任何类型的理解(list
、set
、dict
),因为嵌套范围不直接附加到 class,所以它不无法获得附加到 class 本身的方法所获得的 __class__
定义魔法。
在极少数情况下,您可能希望显式绕过特定的 class 来解析父方法,在这种情况下,您需要显式传递一个与后面不同的 class MRO 而不是它默认拉取的那个。这是一个深奥而可怕的魔法,所以我不推荐它,但我想我有理由这样做过一次。
所有这些都是相对罕见的情况,所以大多数时候,对于纯粹针对 Python 3 的代码,您可以使用无参数 super
,并且只有当你不能出于任何原因使用它时才回退到显式传递参数。无参数super
更干净,更快,并且在实时开发期间可以更正确(如果你替换 MyClass
,旧版本 class 的实例将缓存旧版本并且无参数 super
将继续工作,在哪里查找手动在你的全局中会找到新版本的 class 并爆炸),所以尽可能使用它。
在 Python 3 中,零参数的 super()
已经是 super(__class__, self)
的快捷方式。有关完整说明,请参阅 PEP3135。
Python 2 不是这种情况,所以我猜你找到的大多数代码示例实际上是为 Python 2(或 Python2+3 兼容)编写的
python 中内置的 super()
的一个用例是调用重写的方法。下面是使用 super()
调用 Parent
class 的 echo
函数的简单示例:
class Parent():
def echo(self):
print("in Parent")
class Child(Parent):
def echo(self):
super().echo()
print("in Child")
我见过将 2 个参数传递给 super()
的代码。在那种情况下,签名看起来像 super(subClass, instance)
,其中 subClass
是调用 super()
的子 class,而 instance
是调用的实例,即self
。所以在上面的例子中,super()
行会变成:
super(Child, self).echo()
查看 python3 docs,这两个用例在从 class 内部调用时是相同的。
从 python3 开始,使用 2 个参数调用 super()
是否已完全弃用?如果这只是因为调用重写函数而被弃用,你能举个例子说明为什么其他情况需要它们吗?
我也想知道为什么 python 需要这两个参数?在 python3 中进行 super()
调用时,它们是 injected/evaluated,还是在那种情况下不需要它们?
如果您不传递参数,Python 3 会努力为您提供参数。这有点笨拙,但通常 有效。本质上,它只是假设你的方法的第一个参数是 self
(super
的第二个参数),当 class 定义完成时,它为任何函数提供一个虚拟闭包范围引用 super
或 __class__
将 __class__
定义为您刚刚定义的 class,因此无参数 super()
可以检查堆栈帧以找到 __class__
作为第一个参数。
这通常有效,但在某些情况下无效:
在
staticmethod
s 中(因为第一个参数实际上不是 class),尽管staticmethod
s 不应该真正参与继承层次结构相同,所以这并不完全出乎意料。在以
*args
作为第一个参数的函数中(这是实现任何接受任意关键字参数的方法的唯一安全方法,例如dict
subclasses 在 3.8 之前,当他们引入了仅位置参数时)。如果
super
调用在嵌套范围内,这可以是隐式的,例如生成器表达式,或任何类型的理解(list
、set
、dict
),因为嵌套范围不直接附加到 class,所以它不无法获得附加到 class 本身的方法所获得的__class__
定义魔法。
在极少数情况下,您可能希望显式绕过特定的 class 来解析父方法,在这种情况下,您需要显式传递一个与后面不同的 class MRO 而不是它默认拉取的那个。这是一个深奥而可怕的魔法,所以我不推荐它,但我想我有理由这样做过一次。
所有这些都是相对罕见的情况,所以大多数时候,对于纯粹针对 Python 3 的代码,您可以使用无参数 super
,并且只有当你不能出于任何原因使用它时才回退到显式传递参数。无参数super
更干净,更快,并且在实时开发期间可以更正确(如果你替换 MyClass
,旧版本 class 的实例将缓存旧版本并且无参数 super
将继续工作,在哪里查找手动在你的全局中会找到新版本的 class 并爆炸),所以尽可能使用它。
在 Python 3 中,零参数的 super()
已经是 super(__class__, self)
的快捷方式。有关完整说明,请参阅 PEP3135。
Python 2 不是这种情况,所以我猜你找到的大多数代码示例实际上是为 Python 2(或 Python2+3 兼容)编写的