我理解如何初始化父类以在子类中获取它们的实例属性,但不知道在幕后实现这一点的具体内容。 (注意:这里不要故意使用超级,只是为了清楚说明)
下面我们通过向子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的例子不这样做?
答案 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可以根据需要找到它从类中继承的所有方法。