Python OOP:类属性

类属性

绑定在实例上的属性, 类似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() 时,

c2
c1
Circle class
pi=3.1415926
c2.pi
c1.pi

创建 c1= Circle(),c2=Circle() c1.pi = 3.14 时,

c2
c1
Circle class
访问优先级高
pi=3.1415926
c2.pi
c1.pi
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 的id2068324309328
self.pi 的id2068324310960

在类内使用的 Circle.piself.pi 是两个不同的对象。


小结

其实是通过实例修改类属性,是给实例创建了一个与类属性同名的实例属性而已,
实例属性访问优先级比类属性高
所以我们优先访问实例属性,它将屏蔽掉对类属性的访问。


所以del “实例的”类属性, 就能访问该类的类属性了。

参考:

  1. (知乎):Python入门 类class 基础篇

end

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

adingable

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值