我想教程是不幸(因为含糊)措词和由
[d] ATA属性重写方法具有相同名称
它实际上指“数据属性重写先前分配的属性/定义的同名方法属性,反之亦然:方法属性覆盖以前分配/定义的同名数据属性。“
“Duh”,你可能会认为“数据属性也覆盖了先前分配的数据属性的同名,那么有什么大不了的,为什么还要提到?赋值和重新赋值(在引用的教程中称为“覆盖”)与变量(无论是否称为“属性”)完全是命令式编程语言的原型特征之一。
好,让我给你介绍
命名空间
Python类的命名空间。那么本教程可能试图告诉我们的是,数据属性和方法属性在之内的一个类共享一个名称空间。
不过,对于不同类别的属性,情况并非如此。如果一个类继承自另一个类,它可以访问其父类的名称。如果名称在继承类中用于方法定义或数据分配,则父类会保留原始值。在孩子阶级,他们只是暂时被遮蔽。如果从子类中删除的名字,它也将再次提供接入到同一个名字的父母的属性:
class A:
x = 111
class B1(A):
x = 123 # Shadows A.x
assert B1.x == 123
del B1.x # But after removing B1's own x attribute ...
assert B1.x == 111 # ... B1.x is just an alias to A.x !
# Shadowing can happen at any time:
class B2(A):
pass
assert B2.x == A.x == 111
B2.x = 5 # shadowing attributes can also be added after the class definition
assert B2.x == 5
assert A.x == 111
del B2.x
assert B2.x == A.x == 111
对比这与重新定义又名重新分配(或“重写”的教程调用它):
class C:
x = 555
def x(self):
print('I am x')
C().x() # outputs "I am x"
del C.x
print(C.x) # AttributeError: 'C' object has no attribute 'x'
方法C.x()
暂时没影子数据属性C.x
。它取代了它,所以当我们删除该方法时,x
在C
内完全丢失,而不是在该名称下重新显示的数据属性。
多个命名空间
实例化增加了对阴影另一个命名空间,因此另一个机会:
a = A()
assert a.x == 111 # instance namespace includes class namespace
a.x = 1000
assert a.x == 1000
assert A.x == 111 # class attribute unchanged
del a.x
assert a.x == 111 # sees A.x again
事实上,所有的Python(嵌套)命名空间工作方式:封装,模块,类,函数和方法,实例对象,内部类,嵌套函数...
当读取变量时,命名空间层次结构将自下而上地走到名称被找到。 (读这里的意思是找到变量名称所绑定的值(对象,函数/方法或内置),如果该值是可变的,则也可以用于更改该值。)
On另一方面,在设置(定义或重新定义)变量时,将使用当前名称空间的名称:如果名称已经存在于该名称空间中(而不是仅从其他名称空间包含)新创建的名称,如果它以前不存在。
变量可以遮蔽其他变量...方法和属性与类和函数都 –