上篇文章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中的类属性和实例属性引发的一个坑-续相关推荐

  1. python新式类和经典类区别_Python中新式类和经典类的区别,钻石继承

    1)首先,写法不一样: class A: pass class B(object): 2)在多继承中,新式类采用广度优先搜索,而旧式类是采用深度优先搜索. 3)新式类更符合OOP编程思想,统一了pyt ...

  2. python中类和对象的内容_python中的类和对象

    摘要:本文主要介绍了python中的类和对象的基础内容.由于在c++中对类和对象已经有了较为深刻的认识,所以此部分就是主要熟悉一下创建方法和使用方法. 1.类.对象的创建和简单使用 主要观察创建类的方 ...

  3. Python基础_第5章_Python中的数据序列

    Python基础_第5章_Python中的数据序列 文章目录 Python基础_第5章_Python中的数据序列 Python中的数据序列 一.字典--Python中的==查询==神器 1.为什么需要 ...

  4. Python基础_第3章_Python中的循环结构

    Python基础_第3章_Python中的循环结构 文章目录 Python基础_第3章_Python中的循环结构 Python中的循环结构 一.回顾分支练习题 1.判断是否为一个合法三角形 2.求世界 ...

  5. python类和对象介绍_python中的类,对象,方法,属性等介绍

    注:这篇文章写得很好.加底纹的是我自己的理解 python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性( ...

  6. python里object是什么类型_Python中的object这个叫做基类的类,它的属性和行为都有哪些?...

    声明:以下仅为个人学习Python过程中总结的比较自洽的理解,事实上Python面向对象模型可能没那么简单.经查阅,Python在以前的版本还有不继承自object的类,叫做经典类. 用dir(obj ...

  7. python元类的使用_python中元类用法实例

    本文实例讲述了python中元类用法,分享给大家供大家参考.具体方法分析如下: 1.元类(metaclass)是用来创建类的类 2.type(object):返回一个对象的类型,与object.__c ...

  8. python中类的用法_Python中的类和方法使用举例

    成员变量 对象的创建 创建对象的过程称之为实例化,当一个对象被创建后,包含三个方面的特性对象聚丙属性和方法, 句柄用于区分不同的对象, 对象的属性和方法,与类中的成员变量和成员函数对应, obj = ...

  9. python类_Python中的类

    Python和Java都是面向对象的语言,对象从类中获取,类指的是同一类具有相同特征的事物,比如拉布拉多,柯基,哈士奇,它们都是狗,具有狗的相同特征,所以可以被归为一类Dog,Python中类的使用与 ...

最新文章

  1. 请你要幸福 这是 你唯一能为我做到的
  2. 作为JavaScript开发人员,这些必备的VS Code插件你都用过吗?
  3. Docker (2)与虚拟机的比较
  4. 通过OracleDataReader来读取BLOB类型的数据 (转载)
  5. 用原生js封装get方法
  6. shell与其他语言不同点
  7. 如何生成 Flink 作业的交互式火焰图?
  8. ICDAR 2019 论文下载
  9. KubeEdge led部署
  10. 使用keras理解LSTM
  11. 在哪里买腾讯云服务器,在哪查看我的腾讯云服务器购买记录?
  12. OPNsense用户手册-高可用性和硬件故障转移
  13. python上楼梯问题_python解决上楼梯问题
  14. jQuery读取Table表格数据
  15. Android音频子系统(十五)------Audio调试经验
  16. 微信公众号如何设置关键词回复Word/Excel/pdf/ppt等文件?
  17. sqli-lbs:Less-5~10通关详解
  18. Ms Sql Server 2000 个人绿色版 5.62
  19. 计算机保密dss是啥,什么是DSS?
  20. 面向对象基础案例(2)

热门文章

  1. 2019年,异质图神经网络领域有哪些值得读的顶会论文?
  2. 机器学习理论《统计学习方法》学习笔记:第十一章 条件随机场(CRF)
  3. python3 音乐播放器_python3 音乐播放器
  4. excel 两组数据交点_Python 自动化测试(四):数据驱动
  5. nginx location 匹配 多个规则_你需要知道的Nginx配置二三事
  6. AJAX——AJAX请求递归
  7. Codeforces 1196E Connected Component on a Chessboard
  8. Problem for Nazar
  9. Array Stabilization
  10. android avd 使用方法,Android中Android Virtual Device(AVD)使用教程