在 super 和 init 括号内有参数有什么区别.... super().__init__()
What is the difference between having parameters within super and the init parentheses .... super().__init__()
我知道 super().__init__()
的概念与继承有关,我在 init
中看到过带参数的代码。但是,我遇到了一个代码示例:
class Maze(tk.Tk, object):
def __init__(self):
super(Maze, self).__init__()
参数现在位于 super
括号内。有什么区别,为什么一个可以用于另一个?谢谢
这是 super()
最初的工作方式:
super(Maze, self).__init__()
这也是它在 Python 2 中起作用的唯一方法。
那么,为什么会有争论?
您想调用 class 的 __init__()
,它是 super class 如果 Maze
(可能 tk.Tk
),绑定到 self
。为此,您必须将参数 Maze
和 self
传递给 super
,以便它知道该做什么。
它到底有什么作用?
super(Maze, self).__init__
必须确定 type(self)
才能从中提取 MRO,即 class 相互继承的顺序。
然后,在该列表中,它找到 Maze
正上方的 class,并在 class 或任何 class 中查找 __init__
] 它上面。当它找到它时,它将 __init__
init 方法绑定到 self
(即修复它的第一个参数,所以你不必传递它)。
您可以自己实现 super
的那个版本。它会是这样的:
class my_super:
def __init__(self, cls, obj):
self.cls = cls
self.obj = obj
def __getattribute__(self, method_name):
cls = object.__getattribute__(self, 'cls')
obj = object.__getattribute__(self, 'obj')
mro = type(obj).__mro__
mro_above_cls = mro[mro.index(cls)+1:]
for super_cls in mro_above_cls:
if hasattr(super_cls, method_name):
method = getattr(super_cls, method_name)
return functools.partial(method, self)
请注意,您根本不必从方法中调用它。你可以这样做:
class A:
def f(self):
print('A')
class B(A):
def f(self):
print('B')
a = A()
b = B()
super(B, b).f() # prints: A
my_super(B, b).f() # prints: A
没有参数的版本呢?
super(Maze, self).__init__()
非常明确,但几乎所有 Python 代码总是使用当前 class 和 self 作为参数,因此 Python 3 通过提供知道你想要什么的魔法super()
。
我知道 super().__init__()
的概念与继承有关,我在 init
中看到过带参数的代码。但是,我遇到了一个代码示例:
class Maze(tk.Tk, object):
def __init__(self):
super(Maze, self).__init__()
参数现在位于 super
括号内。有什么区别,为什么一个可以用于另一个?谢谢
这是 super()
最初的工作方式:
super(Maze, self).__init__()
这也是它在 Python 2 中起作用的唯一方法。
那么,为什么会有争论?
您想调用 class 的 __init__()
,它是 super class 如果 Maze
(可能 tk.Tk
),绑定到 self
。为此,您必须将参数 Maze
和 self
传递给 super
,以便它知道该做什么。
它到底有什么作用?
super(Maze, self).__init__
必须确定 type(self)
才能从中提取 MRO,即 class 相互继承的顺序。
然后,在该列表中,它找到 Maze
正上方的 class,并在 class 或任何 class 中查找 __init__
] 它上面。当它找到它时,它将 __init__
init 方法绑定到 self
(即修复它的第一个参数,所以你不必传递它)。
您可以自己实现 super
的那个版本。它会是这样的:
class my_super:
def __init__(self, cls, obj):
self.cls = cls
self.obj = obj
def __getattribute__(self, method_name):
cls = object.__getattribute__(self, 'cls')
obj = object.__getattribute__(self, 'obj')
mro = type(obj).__mro__
mro_above_cls = mro[mro.index(cls)+1:]
for super_cls in mro_above_cls:
if hasattr(super_cls, method_name):
method = getattr(super_cls, method_name)
return functools.partial(method, self)
请注意,您根本不必从方法中调用它。你可以这样做:
class A:
def f(self):
print('A')
class B(A):
def f(self):
print('B')
a = A()
b = B()
super(B, b).f() # prints: A
my_super(B, b).f() # prints: A
没有参数的版本呢?
super(Maze, self).__init__()
非常明确,但几乎所有 Python 代码总是使用当前 class 和 self 作为参数,因此 Python 3 通过提供知道你想要什么的魔法super()
。