python 中超级方法的隐含参数
Implied parameters for super method in python
在一门关于多重继承的课程中,我遇到了这段漂亮的代码。
class First(object):
def __init__(self):
super(First, self).__init__()
print("first")
class Second(object):
def __init__(self):
super(Second, self).__init__()
print("second")
class Third(Second,First):
def __init__(self):
super(Third, self).__init__()
print("third")
Third();
输出:
first
second
third
我有点害怕,所以我开始研究为什么这个东西能起作用。我发现 a lovely article about this matter 很好地解释了 super
背后的机制。
然后我开始玩代码,发现大部分代码其实都是多余的。我一步一步地修剪东西,直到只剩下这个可怜的骨架。
class First():
def __init__(self):
super().__init__()
print("first")
class Second():
def __init__(self):
super().__init__()
print("second")
class Third(Second,First):
def __init__(self):
super().__init__()
print("third")
Third();
这会产生完全相同的输出。现在对于 object
,我知道这可以省略,因为所有 classes 都派生自基数 class object
。那里没有问题。但是我不太明白传递给 super
方法的参数背后的含义。所以我做了这个最后的调整来检查这是否也有效:
class First():
def __init__(self):
super().__init__()
print("first")
class Second():
def __init__(self):
super().__init__()
print("second")
class Third(Second,First):
def __init__(self):
super(self).__init__()
print("third")
Third();
输出:
TypeError: super() argument 1 must be type, not Third
我可以理解在这种情况下self
指的是Third
。在 super(Third,self)
的情况下,Third
指的是 class ,这足以作为我想的类型。那么在调用 super
方法时,总是隐含所有这些冗余部分是否正确?除了我已经找到的 link 之外,还有人有关于这些机制的一些很酷的文档吗?似乎调用它们的顺序与列出 class 参数的顺序相反。
反转为 class Third(First,Second)
给出输出:
second
first
third
如果对此事有更多了解,我们将不胜感激。
您的顶级示例代表 super
的第一个实现。该实现在以后的版本中变得更加智能,因此您应该使用第二个示例。另一个只是过时了。如果您使用多重继承,您可以将正确的父 class 传递给 super
,但这是一种特殊情况。
当 super
被创建时,在 Python 2.x 的日子里,它的参数(class 你想要“超级”的,以及您调用该方法的实例)需要明确。
从语言的角度来看,super
是一个没有特殊处理的普通调用。
在创建 Python 3 时,人们同意调用超 classes 中的方法很常见,因此值得特殊的语言处理,因此它是:
在 Python 3 中,调用 super
变得非常特殊,它由编译器本身处理(不是语言 运行time - 编译器,运行s,虽然在一种透明的方式,在与实际 运行 程序完全分开的循环中)。编译器安排创建一个隐藏的局部变量 - 它称为 __class__
,而无参数 super()
调用实际上是 super(__class__, self)
。 __class__
指向在外部 class
语句体中定义的 class。这种机制实际上是在其他情况下发生的更“幕后发生的神奇事情”之一,非常明确,Python。
填入参数的 super()
的旧的、明确的形式当然仍然有效。
发现其中一些“隐形”机制的一个好方法是尝试将无参数 super
调用放在普通函数中,而不是方法中:尝试时您会看到早期错误运行代码。
在一门关于多重继承的课程中,我遇到了这段漂亮的代码。
class First(object):
def __init__(self):
super(First, self).__init__()
print("first")
class Second(object):
def __init__(self):
super(Second, self).__init__()
print("second")
class Third(Second,First):
def __init__(self):
super(Third, self).__init__()
print("third")
Third();
输出:
first
second
third
我有点害怕,所以我开始研究为什么这个东西能起作用。我发现 a lovely article about this matter 很好地解释了 super
背后的机制。
然后我开始玩代码,发现大部分代码其实都是多余的。我一步一步地修剪东西,直到只剩下这个可怜的骨架。
class First():
def __init__(self):
super().__init__()
print("first")
class Second():
def __init__(self):
super().__init__()
print("second")
class Third(Second,First):
def __init__(self):
super().__init__()
print("third")
Third();
这会产生完全相同的输出。现在对于 object
,我知道这可以省略,因为所有 classes 都派生自基数 class object
。那里没有问题。但是我不太明白传递给 super
方法的参数背后的含义。所以我做了这个最后的调整来检查这是否也有效:
class First():
def __init__(self):
super().__init__()
print("first")
class Second():
def __init__(self):
super().__init__()
print("second")
class Third(Second,First):
def __init__(self):
super(self).__init__()
print("third")
Third();
输出:
TypeError: super() argument 1 must be type, not Third
我可以理解在这种情况下self
指的是Third
。在 super(Third,self)
的情况下,Third
指的是 class ,这足以作为我想的类型。那么在调用 super
方法时,总是隐含所有这些冗余部分是否正确?除了我已经找到的 link 之外,还有人有关于这些机制的一些很酷的文档吗?似乎调用它们的顺序与列出 class 参数的顺序相反。
反转为 class Third(First,Second)
给出输出:
second
first
third
如果对此事有更多了解,我们将不胜感激。
您的顶级示例代表 super
的第一个实现。该实现在以后的版本中变得更加智能,因此您应该使用第二个示例。另一个只是过时了。如果您使用多重继承,您可以将正确的父 class 传递给 super
,但这是一种特殊情况。
当 super
被创建时,在 Python 2.x 的日子里,它的参数(class 你想要“超级”的,以及您调用该方法的实例)需要明确。
从语言的角度来看,super
是一个没有特殊处理的普通调用。
在创建 Python 3 时,人们同意调用超 classes 中的方法很常见,因此值得特殊的语言处理,因此它是:
在 Python 3 中,调用 super
变得非常特殊,它由编译器本身处理(不是语言 运行time - 编译器,运行s,虽然在一种透明的方式,在与实际 运行 程序完全分开的循环中)。编译器安排创建一个隐藏的局部变量 - 它称为 __class__
,而无参数 super()
调用实际上是 super(__class__, self)
。 __class__
指向在外部 class
语句体中定义的 class。这种机制实际上是在其他情况下发生的更“幕后发生的神奇事情”之一,非常明确,Python。
填入参数的 super()
的旧的、明确的形式当然仍然有效。
发现其中一些“隐形”机制的一个好方法是尝试将无参数 super
调用放在普通函数中,而不是方法中:尝试时您会看到早期错误运行代码。