python类属性、实例属性、私有属性、保护属性
python类属性与实例属性
定义
class A:
class_name = "calss" # 类属性
def __init__(self):
self.object_name = "object" # 实例属性
if __name__ == "__main__":
print(A.class_name) # 正确,类名可以访问类属性
# print(A.object_name) # 错误,类名不可以访问实例属性
a = A()
print(a.object_name) # 正确,实例名可以访问实例属性
print(a.class_name) # 正确,如果实例中没有和类属性同名的实例属性,则类属性会为实例提供默认值,此时实例名能访问类属性
a.class_name = "I am a" # 通过实例属性无法更改类属性的值
print(A.class_name, a.class_name)
输出:
calss
object
calss
calss I am a
- class_name是类属性,写在__init__方法之外,属于类,不断实例化了多少个实例,类属性在内存中始终只有一份。
- object_name是实例属性,写在__init__方法内,self是实例本身的引用。
类属性为实例属性提供默认值
如上例子,当用实例a来访问属性a.class_name时:
- 如果a有class_name这个实例属性,则直接访问。
- 如果a没有的话,则通过实例a访问到了类属性class_name,即类属性为实例属性提供默认值。
实例属性覆盖类属性
当实例属性与类属性重名时,通过实例访问时实例属性会覆盖类属性,由于python中属性是可以动态添加的,如上例子中,本来没有实例属性class_name,但是通过实例a动态添加了一个实例属性class_name,那么下次再通过实例a访问class_name时访问到的就是实例属性,而不是类属性了。
修改类属性
- 通过实例修改类属性的话,实际上会新添加一个新的实例属性,原先类属性是不会变的。
- 首先当然可以通过类名修改类属性。
A.class_name = "I am A" print(A.class_name) - 但是一般用一个更python风格的方法。对于公开的类属性,是会被子类继承的,因此可以通过创建子类专门定制类属性。
class B(A): class_name = "new class"
python私有属性与保护属性
- python中类属性和实例属性都可以定义为私有的,只需要在属性名前加两个下划线即可,这样在外接直接访问的话会失败,但是如果在属性名前再加一个下划线和类名,则在外界依然可以访问,因为python中不存在真正的私有属性,只是解释器见到两个下划线开头的属性会给它改个名字。
class A: __class_name = "calss" # 类属性 def __init__(self): self.__object_name = "object" # 实例属性 if __name__ == "__main__": a = A() # print(A.__class_name) # 错误,私有类属性不能在类外访问 # print(a.__object_name) # 错误,私有实例属性不能在外部访问 print(A._A__class_name) # 正确 print(a._A__object_name) # 正确
浙公网安备 33010602011771号