python实例属性与类属性_Python中的类属性和实例属性引发的一个坑-续
上篇文章Python 中的类属性和实例属性,我们探讨了类属性和实例属性引发的一个小坑。总结了类属性和实例属性的区别如下:类属性可以被类和实例调用,实例属性只能被实例调用
类属性不会随着实例的调用而改变
类属性的有效作用域只有类,实例属性的有效作用域只有本实例(有效作用域并非官方描述,而是我做的一个类比,大家可与作用域类别)。
其实第二点可以忽略,第三点已经涵盖了。我把文章发给了小伙伴们品读,有小伙伴针对第二三条提出了不同的看法。看如下例子:
class Persion(object):
count = 0
info = {
'name': '小明'
}
info_list = []
def __init__(self):
self.name = '人'
if __name__ == '__main__':
p = Persion()
p.count = 5
print(p.count) # 5
print(Persion.count) # 0
p.count += 5
print(p.count) # 10
print(Persion.count) # 0
p.info['name'] = '小红'
print(p.info) # {'name': '小红'}
print(Persion.info) # {'name': '小红'}
p2 = Persion()
p2.info = {'name': 'Tom'}
print(p2.info) # {'name': 'Tom'}
print(Persion.info) # {'name': '小红'}
实例中,info 的值被修改了,那么是否可以说「实例可以修改类属性」了呢?我们来继续分析,来看 count 和 info 区别,不难想到它们一个是「不可变变量(immutable type)」,一个是「可变变量(mutable type)」,这两种变量类型的区别在于内存的使用。
Python 变量中实际上保存的是内存中值的引用,「不可变变量」修改时,是改变了引用,「可变变量」修改时,是改变了内存块中的值。如下:不可变变量
i = 20
j = 20
print(id(i)) # 4299177184
print(id(j)) # 4299177184 不同变量引用了同一个值
i +=1
print(id(i)) # 4340788480 值变了,变量的引用地址也变了可变变量
d1 = [1, 2, 3]
d2 = [1, 2, 3]
print(id(d1)) # 4514412936
print(id(d2)) # 4511850248 # 相同值,变量的引用地址不同
d1.append(4)
print(id(d1)) # 4514412936 # 值变了,变量的引用地址没变
说回我们讨论的问题,当修改 info 的name key 所对应的值时,实际上是修改了内存块中的值,因为实例p和类Person的 info 属性都是指向了统一内存地址,所以类Person的 info 属性的值也变了。而当我们直接给实例p的 info 属性赋值时,它引用的是另一个内存地址的值,虽然值和类Person的 info 相同,但是引用不同,所以当p的属性修改时,Person的 info 属性没有变化的。
那我们来总结一下:当类的属性为不可变变量时,实例属性是对类属性值的引用,修改实例属性仅仅是修改了引用,不会修改原来的值,即不会修改类属性。
当类的属性为可变变量时,分下面两种情况:当直接修改实例属性时,因为是可变变量,即把内存中的值修改了,所以类属性的值也修改了。
当重新赋值实例属性时,因为和类属性的引用不同,即使值改变了,也不会影响类属性的值。
那么上篇中结论有些不太严谨,需要针对「可变变量」和「不可变变量」做些区分,这里有些类似函数传参时的作用域的关系。大家在实际应用中,一定要注意「可变变量」和「不可变变量」的区别。
更多「可变变量」和「不可变变量」资料可参阅:How do I pass a variable by reference?[1]
Facts and Myths about Python names and values[2]
参考资料
[2] Facts and Myths about Python names and values:
python实例属性与类属性_Python中的类属性和实例属性引发的一个坑-续相关推荐
- python新式类和经典类区别_Python中新式类和经典类的区别,钻石继承
1)首先,写法不一样: class A: pass class B(object): 2)在多继承中,新式类采用广度优先搜索,而旧式类是采用深度优先搜索. 3)新式类更符合OOP编程思想,统一了pyt ...
- python中类和对象的内容_python中的类和对象
摘要:本文主要介绍了python中的类和对象的基础内容.由于在c++中对类和对象已经有了较为深刻的认识,所以此部分就是主要熟悉一下创建方法和使用方法. 1.类.对象的创建和简单使用 主要观察创建类的方 ...
- Python基础_第5章_Python中的数据序列
Python基础_第5章_Python中的数据序列 文章目录 Python基础_第5章_Python中的数据序列 Python中的数据序列 一.字典--Python中的==查询==神器 1.为什么需要 ...
- Python基础_第3章_Python中的循环结构
Python基础_第3章_Python中的循环结构 文章目录 Python基础_第3章_Python中的循环结构 Python中的循环结构 一.回顾分支练习题 1.判断是否为一个合法三角形 2.求世界 ...
- python类和对象介绍_python中的类,对象,方法,属性等介绍
注:这篇文章写得很好.加底纹的是我自己的理解 python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性( ...
- python里object是什么类型_Python中的object这个叫做基类的类,它的属性和行为都有哪些?...
声明:以下仅为个人学习Python过程中总结的比较自洽的理解,事实上Python面向对象模型可能没那么简单.经查阅,Python在以前的版本还有不继承自object的类,叫做经典类. 用dir(obj ...
- python元类的使用_python中元类用法实例
本文实例讲述了python中元类用法,分享给大家供大家参考.具体方法分析如下: 1.元类(metaclass)是用来创建类的类 2.type(object):返回一个对象的类型,与object.__c ...
- python中类的用法_Python中的类和方法使用举例
成员变量 对象的创建 创建对象的过程称之为实例化,当一个对象被创建后,包含三个方面的特性对象聚丙属性和方法, 句柄用于区分不同的对象, 对象的属性和方法,与类中的成员变量和成员函数对应, obj = ...
- python类_Python中的类
Python和Java都是面向对象的语言,对象从类中获取,类指的是同一类具有相同特征的事物,比如拉布拉多,柯基,哈士奇,它们都是狗,具有狗的相同特征,所以可以被归为一类Dog,Python中类的使用与 ...
最新文章
- 请你要幸福 这是 你唯一能为我做到的
- 作为JavaScript开发人员,这些必备的VS Code插件你都用过吗?
- Docker (2)与虚拟机的比较
- 通过OracleDataReader来读取BLOB类型的数据 (转载)
- 用原生js封装get方法
- shell与其他语言不同点
- 如何生成 Flink 作业的交互式火焰图?
- ICDAR 2019 论文下载
- KubeEdge led部署
- 使用keras理解LSTM
- 在哪里买腾讯云服务器,在哪查看我的腾讯云服务器购买记录?
- OPNsense用户手册-高可用性和硬件故障转移
- python上楼梯问题_python解决上楼梯问题
- jQuery读取Table表格数据
- Android音频子系统(十五)------Audio调试经验
- 微信公众号如何设置关键词回复Word/Excel/pdf/ppt等文件?
- sqli-lbs:Less-5~10通关详解
- Ms Sql Server 2000 个人绿色版 5.62
- 计算机保密dss是啥,什么是DSS?
- 面向对象基础案例(2)
热门文章
- 2019年,异质图神经网络领域有哪些值得读的顶会论文?
- 机器学习理论《统计学习方法》学习笔记:第十一章 条件随机场(CRF)
- python3 音乐播放器_python3 音乐播放器
- excel 两组数据交点_Python 自动化测试(四):数据驱动
- nginx location 匹配 多个规则_你需要知道的Nginx配置二三事
- AJAX——AJAX请求递归
- Codeforces 1196E Connected Component on a Chessboard
- Problem for Nazar
- Array Stabilization
- android avd 使用方法,Android中Android Virtual Device(AVD)使用教程