gpt4 book ai didi

Python super 方法和调用替代方法

转载 作者:IT老高 更新时间:2023-10-28 20:25:24 30 4
gpt4 key购买 nike

我到处都能看到父类(super class)方法应该被调用的例子:

super(SuperClass, instance).method(args)

这样做有什么缺点吗:

SuperClass.method(instance, args)

最佳答案

考虑以下情况:

class A(object):
def __init__(self):
print('Running A.__init__')
super(A,self).__init__()
class B(A):
def __init__(self):
print('Running B.__init__')
# super(B,self).__init__()
A.__init__(self)

class C(A):
def __init__(self):
print('Running C.__init__')
super(C,self).__init__()
class D(B,C):
def __init__(self):
print('Running D.__init__')
super(D,self).__init__()

foo=D()

所以类形成了所谓的继承菱形:

    A
/ \
B C
\ /
D

运行代码产生

Running D.__init__
Running B.__init__
Running A.__init__

这很糟糕,因为 C__init__ 被跳过了。原因是B__init__直接调用A__init__

super的目的是解决继承菱形。如果你取消评论

# super(B,self).__init__()

并注释掉

A.__init__(self) 

代码产生更理想的结果:

Running D.__init__
Running B.__init__
Running C.__init__
Running A.__init__

现在所有的 __init__ 方法都被调用了。请注意,在您定义 B.__init__ 时,您可能认为 super(B,self).__init__() 与调用相同A.__init__(self),但你错了。在上述情况下,super(B,self).__init__()实际上调用了C.__init__(self)

天哪,BC 一无所知,而 super(B,self) 却知道调用 C__init__?原因是因为 self.__class__.mro() 包含 C。换句话说,self(或上面的foo)知道C

所以要小心——这两者是不可替代的。它们可以产生截然不同的结果。

使用 super has pitfalls.在继承图中的所有类之间需要相当程度的协调。 (例如,它们必须具有相同的 __init__ 调用签名,因为任何特定的 __init__ 都不知道哪个其他 __init__ super 可能会调用 next,或者否则 use **kwargs .) 此外,您必须始终如一地使用 super。跳过它一次(如上面的例子),你就破坏了 super 的全部目的。查看链接了解更多陷阱。

如果您可以完全控制类层次结构,或者避免继承菱形,则不需要 super

关于Python super 方法和调用替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5033903/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com