2016-06-01 157 views
0

我知道如何初始化一个父类,以便在子类中获得它们的实例属性,但不完全是幕后操作来实现这一点。 (注意:这里不是特意使用,只是为了说明清楚)初始化父类实例的属性

下面我们通过给孩子class B增加一个额外的属性y来扩展class A。如果您在实例化b=B()后查看课程词典,我们正确地看到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__叫什么名字?价值如何被约束?这与查找方法有所不同,因为您不是按需搜索继承链,而是实际将值分配给继承类的实例dict。

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

回答

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可以根据需要找到它从类继承的所有方法。