您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python超级方法和调用替代方法

Python超级方法和调用替代方法

请考虑以下情况:

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__

不好,因为跳过了Cs __init__。其原因是因为B__init__调用A__init__直接。

。如果您取消评论

# 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)

圣烟,B一无所知C,却super(B,self)知道调用C__init__?原因是因为self.__class__.mro()包含C。换句话说,self(或以上所述foo)了解C

所以要小心-两者不可互换。它们可以产生截然不同的结果。

使用super 有陷阱。继承图中的所有类之间需要相当大的协调。(例如,它们必须具有相同的呼叫签名__init__,因为任何特定的__init__人都不知道__init__super接下来会呼叫另一个,或者使用**kwargs。)此外,您必须在super任何地方都保持一致。跳过一次(如上例所示),您将失去的全部目的super。请参阅链接以了解更多陷阱。

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

python 2022/1/1 18:29:12 有460人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶