由于您实例化了一个B
对象,B.__init__
因此被调用并添加了一个属性z
。该属性现在存在于对象中。这不是一些奇怪的重载的神奇共享局部变量B
方法,它以某种方式变得无法访问其他地方编写的代码。没有这样的事情。当它被传递给超类的方法时,它们都不会self
成为不同的对象(如果发生这种情况,多态性应该如何工作?)。
也没有声明A
对象没有这样的对象(try o = A(); a.z = whatever
),也不需要是1self
的实例。事实上,根本没有任何声明。一切都是“继续尝试”;这是一种动态语言的定义(不仅仅是动态类型)。do
A
该对象的z
属性始终“无处不在” 2,无论从哪个“上下文”访问它。为解决过程或其他几种行为定义代码的位置无关紧要3。出于同样的原因,尽管没有用 C 语言编写代码,您仍可以访问列表的方法listobject.c
;-) 不,方法并不特殊。它们也只是对象(实际上是 type 的实例function
)并且涉及完全相同的查找序列。
1这是一个小小的谎言;在 Python 2 中,A.do
将是“绑定方法”对象,如果第一个参数不满足,它实际上会引发错误isinstance(A, <first arg>)
。
2直到它被del
或它的功能等价物(delattr
和朋友)之一删除。
3好吧,有名称修饰,理论上,代码可以检查堆栈,从而检查调用者代码对象,从而检查其源代码的位置。