正在初始化 parent class 实例属性
Initializing parent class instance attributes
我了解如何初始化 parent class 以在 child class 中获取它们的实例属性,但不完全了解幕后发生的事情这个。 (注意:这里不是故意使用 super,只是为了说明清楚)
下面我们通过向 child class B
添加一个额外的属性 y
来扩展 class A
。如果在实例化 b=B()
之后查看 class 字典,我们会正确地看到 b.x
(继承自 class A
)和 b.y
。
我假设在高层次上这是通过调用 A.__init__(self,x=10)
执行类似于 b.x=10
的操作(正常实例属性的分配方式)在 __init__
中完成的class B
个。我有点不清楚,因为您正在调用 class A
的 __init__
,而不是 class B
,但 class B
仍然会相应地更新它的实例属性。 class A's
__init__
如何知道更新 b's
实例属性。
这与继承方法不同,后者 b
object 在其特定命名空间中没有显式继承方法,但会在调用缺失方法时查找继承链。使用该属性,该方法实际上位于 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
下面我们继承自built-in列表。在这里,与上面类似,因为我们在 Foolist 的 __init__
中调用列表的 __init__
方法,我希望看到一个包含元素的实例字典,但它无处可寻。值 123
在 object 某处,可以通过打印 alist
看出,但不在实例字典中。
class Foolist(list):
def __init__(self, elems):
list.__init__(self, elems)
alist = Foolist('123')
那么当从 child 的 __init__
调用 parent 的 __init__
时,继承 class 到底发生了什么?值是如何绑定的?它似乎与方法查找不同,因为您不是按需搜索继承链,而是实际为继承 class 的实例字典赋值。
调用 parents init 是如何填充它的 child 的实例字典的?为什么 Foolist 示例不这样做?
答案很简单:self
。
作为一个非常粗略的概述,当实例化一个 class 时,一个对象 被创建。这或多或少从字面上看只是一个没有任何附属关系的空容器。*然后这个 "empty container" 被传递给正在实例化的 class 的 __init__
方法,在那里它变成.. . self
论点!然后,您将在该对象上设置一个属性。然后,您将调用另一个 class 的 __init__
方法, 明确地将您的特定 self
对象传递给该方法;该方法然后将另一个属性添加到对象。
这实际上是每个实例方法的工作原理。每个方法隐式接收 "current object" 作为其第一个参数 self
。调用父项的 __init__
方法时,实际上是在使该对象的传递非常明确。
您可以用这个简单的例子来模拟该行为:
def init_a(obj):
obj.x = 10
def init_b(obj):
init_a(obj)
obj.y = 20
o = {}
init_b(o)
* 对象不完全是 "empty",对象上设置了特定的属性,这些属性与特定的 class 建立了从属关系,因此对象是 "an instance of" 某个 class,而Python可以根据需要定位它从class继承的所有方法。
我了解如何初始化 parent class 以在 child class 中获取它们的实例属性,但不完全了解幕后发生的事情这个。 (注意:这里不是故意使用 super,只是为了说明清楚)
下面我们通过向 child class B
添加一个额外的属性 y
来扩展 class A
。如果在实例化 b=B()
之后查看 class 字典,我们会正确地看到 b.x
(继承自 class A
)和 b.y
。
我假设在高层次上这是通过调用 A.__init__(self,x=10)
执行类似于 b.x=10
的操作(正常实例属性的分配方式)在 __init__
中完成的class B
个。我有点不清楚,因为您正在调用 class A
的 __init__
,而不是 class B
,但 class B
仍然会相应地更新它的实例属性。 class A's
__init__
如何知道更新 b's
实例属性。
这与继承方法不同,后者 b
object 在其特定命名空间中没有显式继承方法,但会在调用缺失方法时查找继承链。使用该属性,该方法实际上位于 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
下面我们继承自built-in列表。在这里,与上面类似,因为我们在 Foolist 的 __init__
中调用列表的 __init__
方法,我希望看到一个包含元素的实例字典,但它无处可寻。值 123
在 object 某处,可以通过打印 alist
看出,但不在实例字典中。
class Foolist(list):
def __init__(self, elems):
list.__init__(self, elems)
alist = Foolist('123')
那么当从 child 的 __init__
调用 parent 的 __init__
时,继承 class 到底发生了什么?值是如何绑定的?它似乎与方法查找不同,因为您不是按需搜索继承链,而是实际为继承 class 的实例字典赋值。
调用 parents init 是如何填充它的 child 的实例字典的?为什么 Foolist 示例不这样做?
答案很简单:self
。
作为一个非常粗略的概述,当实例化一个 class 时,一个对象 被创建。这或多或少从字面上看只是一个没有任何附属关系的空容器。*然后这个 "empty container" 被传递给正在实例化的 class 的 __init__
方法,在那里它变成.. . self
论点!然后,您将在该对象上设置一个属性。然后,您将调用另一个 class 的 __init__
方法, 明确地将您的特定 self
对象传递给该方法;该方法然后将另一个属性添加到对象。
这实际上是每个实例方法的工作原理。每个方法隐式接收 "current object" 作为其第一个参数 self
。调用父项的 __init__
方法时,实际上是在使该对象的传递非常明确。
您可以用这个简单的例子来模拟该行为:
def init_a(obj):
obj.x = 10
def init_b(obj):
init_a(obj)
obj.y = 20
o = {}
init_b(o)
* 对象不完全是 "empty",对象上设置了特定的属性,这些属性与特定的 class 建立了从属关系,因此对象是 "an instance of" 某个 class,而Python可以根据需要定位它从class继承的所有方法。