类属性
绑定在实例上的属性, 类似java类中的静态变量/类变量——类的所有实例共享数据
实验代码1:
# encoding: utf-8
"""
update-time : 2021-08-17
author : 一起偷偷打螺丝吗
blog : https://blog.csdn.net/m0_46156900
"""
class Circle:
pi = 3.1415926 # 类属性
if __name__ == '__main__':
c1 = Circle()
c2 = Circle()
print('-'*10+'访问一下c1, c2的对象属性pi'+'-'*10)
print('c1.pi = ',c1.pi)
print('c1.pi = ',c2.pi)
print('-'*10+'修改c1.pi=3.14'+'-'*10)
c1.pi = 3.14
print('实例对象的对象属性pi 改变:', c1.pi)
print('但是类属性Circle.pi没改变:',Circle.pi)
print('-' * 10 + 'delete c1.pi' + '-' * 10)
del c1.pi
print('虽然删掉了c1.pi,但是c1.pi可以重新访问Circle.pi,\nc1.pi = ',c1.pi)
print('-'*10+'修改类属性Circle.pi'+'-'*10)
Circle.pi = 3.14
print('Circle.pi = ',Circle.pi)
print('-' * 10 + '访问一下c1, c2的对象属性pi' + '-' * 10)
print('c1.pi = ', c1.pi)
print('c1.pi = ', c2.pi)
del c1.pi
输出如下:
----------访问一下c1, c2的对象属性pi----------
c1.pi = 3.1415926
c1.pi = 3.1415926
----------修改c1.pi=3.14----------
实例对象的对象属性pi 改变: 3.14
但是类属性Circle.pi没改变: 3.1415926
----------delete c1.pi----------
虽然删掉了c1.pi,但是c1.pi可以重新访问Circle.pi,
c1.pi = 3.1415926
----------修改类属性Circle.pi----------
Circle.pi = 3.14
----------访问一下c1, c2的对象属性pi----------
c1.pi = 3.14
c1.pi = 3.14
Process finished with exit code 0
代码中 del c1.pi
删掉不是类属性(Circle.pi
) ,而是实例属性 c1.pi
但,没有给 c1.pi
赋值,也就是给 c1
创建实例变量 c1.pi
, 而直接 del c1.pi
就, 就,报错! 问题是,为什么报错?
Traceback (most recent call last):
File "C:\Users\sample1.py", line 29, in <module>
del c1.pi
AttributeError: pi
看第二个实验例子:
实验代码2:
# encoding: utf-8
"""
update-time : 2021-08-17
author : 一起偷偷打螺丝吗
blog : https://blog.csdn.net/m0_46156900
"""
class Circle:
pi = 3.1415926 # 类属性
if __name__ == '__main__':
c1 = Circle()
c2 = Circle()
print("-"*10+"比较一下对象属性和类属性的内存id"+'-'*10)
print("c1.pi 的id:", id(c1.pi))
print("c2.pi 的id:", id(c2.pi))
print('Circle.pi 的id:', id(Circle.pi))
print("-"*10+"赋值(创建)对象属性后,对象属性和类属性的内存id"+'-'*10)
c1.pi = 999
print("c1.pi 的id:", id(c1.pi))
print('Circle.pi 的id:', id(Circle.pi))
输出如下:
----------比较一下对象属性和类属性的内存id----------
c1.pi 的id: 1781143344944
c2.pi 的id: 1781143344944
Circle.pi 的id: 1781143344944
----------赋值(创建)对象属性后,对象属性和类属性的内存id----------
c1.pi 的id: 2603693021104
Circle.pi 的id: 1781143344944
画个图吧, 更好理解:
创建 c1= Circle(),c2=Circle()
时,
创建 c1= Circle(),c2=Circle() c1.pi = 3.14
时,
可见, 没有给实例对象重新赋值的时候,所有实例的属性都指向类属性。
修改实例的类属性值(c1.pi),并不会 影响类属性值(Circle.pi)。
它实际上并没有修改类属性,而是给实例绑定了一个实例属性。
注意
在一个类中,比如如下
>>> class Circle:
pi = 3.1415926 # 类属性
def __init__(self, inst_pi=3.1415962):
self.pi = inst_pi
def info(self):
print("Circle.pi 的id为 %d" %id(Circle.pi))
print("self.pi 的id为 %d" %id(self.pi))
>>> Circle().info()
Circle.pi 的id为 2068324309328
self.pi 的id为 2068324310960
在类内使用的 Circle.pi
和 self.pi
是两个不同的对象。
小结
其实是通过实例修改类属性,是给实例创建了一个与类属性同名的实例属性而已,
实例属性访问优先级比类属性高,
所以我们优先访问实例属性,它将屏蔽掉对类属性的访问。
所以del “实例的”类属性, 就能访问该类的类属性了。
参考:
- (知乎):Python入门 类class 基础篇
end