初始化父类实例属性

时间:2016-06-01 02:08:00

标签: python inheritance super

我理解如何初始化父类以在子类中获取它们的实例属性,但不知道在幕后实现这一点的具体内容。 (注意:这里不要故意使用超级,只是为了清楚说明)

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

我假设在较高级别,这是通过调用A.__init__(self,x=10)来执行类似于b.x=10(在__init__ class B范围内分配普通实例属性的方式来实现的。 {1}}。我有点不清楚,因为您拨打了__init__ class A,而不是class B,但class B仍然相应地更新了它的实例属性。 class A's __init__如何知道更新b's实例属性。

这与继承的方法不同,其中b对象在其特定的命名空间中没有显式的继承方法,但在调用缺少的方法时查找继承链。使用该属性,该方法实际上位于b的命名空间(它的实例dict)中。

  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看到,但不能在实例dict中看到。

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

alist = Foolist('123')

那么当从孩子__init__调用父母__init__时,继承类到底发生了什么?价值观是如何受约束的?它似乎与方法查找不同,因为您不是按需搜索继承链,而是实际将值分配给继承类的实例dict。

如何打电话给父母初学者填写孩子的实例词典?为什么Foolist的例子不这样做?

1 个答案:

答案 0 :(得分:2)

答案很简单: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可以根据需要找到它从类中继承的所有方法。