【问题标题】:super().__init__() and the __dict__ method [duplicate]super().__init__() 和 __dict__ 方法[重复]
【发布时间】:2020-08-14 04:35:34
【问题描述】:

直接初始化继承的类而不是使用 super().__init__() 时,__dict__ 方法不会产生相同的结果。为什么?:

class A:
    def __init__(self):
        self.att_a = "A"    

class B:
    def __init__(self):
        self.att_b = "B"

class C(A, B):

    def __init__(self):
        A.__init__(self)
        B.__init__(self)
        self.att_c = "C"

    def get_att(self):
        print(self.__dict__) 

c = C()

c.get_att()

结果:{'attA': 'A', 'attB': 'B', 'attC': 'C'}

为什么使用super().__init__() 不会产生相同的结果:

class A:
    def __init__(self):
        self.att_a = "A"    

class B:
    def __init__(self):
        self.att_b = "B"

class C(A, B):

    def __init__(self):
        super().__init__() # Modification
        self.att_c = "C"

    def get_att(self):
        print(self.__dict__) 

c = C()

c.get_att()

结果:{'att_a': 'A', 'att_c': 'C'}

【问题讨论】:

  • 另见stackoverflow.com/questions/9575409。注意这个问题与__dict__无关。这只是与调用什么和不调用什么有关:在您的 super() 示例中,A.__init__() 被调用而 B.__init__() 不被调用。

标签: python


【解决方案1】:

super().__init__ 只调用 MRO 中的 next 方法。 A.__init__ 没有调用super().__init__,所以B.__init__ 永远不会被调用。

所有的类都必须合作。

class A:
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.att_a = "A"    


class B:
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.att_b = "B"


class C(A, B):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.att_c = "C"

    def get_att(self):
        print(self.__dict__) 


# The MRO of C is [C, A, B, object]
# C.__init__ calls A.__init__
# A.__init__ calls B.__init__
# B.__init__ calls object.__init__
# object, as the root of the object hierarchy,
# does not use super().
c = C()

c.get_att()

在所有定义中添加**kwargs 是为了容纳您甚至可能不知道的扩展ABC 的任何类。定义__init__ 的类无法提前知道super() 下一步将调用哪个类。

【讨论】:

  • 我正准备将问题标记为重复问题,但我不得不说,之前的问题的答案都没有这个问题那么清楚。
  • 我通常对回答这样的问题感到有点内疚,但在许多情况下,我觉得针对特定问题量身定制的答案比类似问题的链接更有用。
【解决方案2】:

__init__()MRO 解析的任何其他方法一样,即。只调用一个实现。 多重继承只允许在所有子树中找到“正确”的方法定义:https://docs.python.org/3/library/functions.html#super

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-06
    • 2018-11-06
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 2012-08-09
    相关资源
    最近更新 更多