【问题标题】:Initializing parent class instance attributes初始化父类实例属性
【发布时间】:2016-06-01 02:07:59
【问题描述】:

我了解如何初始化父类以在子类中获取它们的实例属性,但不完全了解幕后发生的事情来完成此操作。 (注意:这里不是故意用super,只是为了说明清楚)

下面我们通过向子class B 添加一个额外的属性y 来扩展class A。如果您在实例化 b=B() 后查看类 dict,我们可以看到 b.x(继承自 class A)和 b.y

我假设在较高级别上,这是通过在 class B__init__ 中调用 A.__init__(self,x=10) 执行类似于 b.x=10(分配普通实例属性的方式)的方式来完成的。我有点不清楚,因为您调用的是class A__init__,而不是class B,但class B 仍然会相应地更新它的实例属性。 class A's __init__ 怎么知道更新b's 实例属性。

这与b 对象在其特定命名空间中没有显式继承方法的继承方法不同,而是在调用缺少的方法时查找继承链。有了这个属性,方法实际上是在b 的命名空间中(它是实例字典)。

  class A:
        def __init__(self,x):
            self.x = x

    class B(A):
        def __init__(self):
            A.__init__(self,x=10)
            self.y = 1 

    b = B() 
    print(b.__dict__) 
    >>>{x:10,y:1} #x added to instance dict from parent init

下面我们继承自内置列表。在这里,与上面类似,因为我们在 Foolist 的 __init__ 中调用列表的 __init__ 方法,所以我希望看到一个包含 elems 的实例字典,但找不到它。 123 的值在对象中的某处,可以通过打印 alist 看到,但不在实例字典中。

class Foolist(list):
    def __init__(self, elems):
        list.__init__(self, elems)

alist = Foolist('123')

那么,当父级的__init__ 被子级的__init__ 调用时,继承类到底发生了什么?价值观是如何绑定的?它似乎与方法查找不同,因为您不是按需搜索继承链,而是实际上将值分配给继承类的实例字典。

对父母 init 的调用如何填写它的孩子的实例字典?为什么 Foolist 示例不这样做?

【问题讨论】:

    标签: python inheritance super


    【解决方案1】:

    答案很简单:self

    作为一个非常粗略的概述,当实例化一个类时,一个对象被创建。从字面上看,这或多或少只是一个空容器,与任何东西无关。*这个“空容器”然后被传递给正在实例化的类的__init__ 方法,在那里它变成...self 参数!然后,您在该对象上设置一个属性。然后,您将调用不同类的 __init__ 方法,将您的特定 self 对象显式传递给该方法;然后该方法将另一个属性添加到对象。

    这实际上是每个实例方法的工作方式。每个方法都隐式接收“当前对象”作为其第一个参数self。当调用父级的 __init__ 方法时,实际上是在使该对象的传递非常明确。

    您可以通过这个简单的示例来近似该行为:

    def init_a(obj):
        obj.x = 10
    
    def init_b(obj):
        init_a(obj)
        obj.y = 20
    
    o = {}
    init_b(o)
    

    * 对象并不完全是“空的”,对象上设置了特定的属性,这些属性与特定的类建立了联系,因此对象是某个类的“实例”,Python可以定位所有方法它根据需要从类继承。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      • 2020-02-12
      • 1970-01-01
      • 2021-11-21
      • 2017-09-29
      • 1970-01-01
      相关资源
      最近更新 更多