初始化父类实例的属性
我知道如何初始化一个父类,以便在子类中获得它们的实例属性,但不完全是幕后操作来实现这一点。 (注意:这里不是特意使用,只是为了说明清楚)初始化父类实例的属性
下面我们通过给孩子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调用填写它的孩子的实例字典?为什么愚蠢的例子不这样做?
答案很简单: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可以根据需要找到它从类继承的所有方法。