Python 学习之共享引用

文章目录

  • Python 学习之共享引用
    • 什么是共享引用
    • 共享引用和在原处修改(Shared References and In-Place Changes)
    • 共享引用和相等
    • 参考资料

什么是共享引用

假设我们在Python交互模式下输入以下语句:

>>> a = 3
>>> b = a

实际的效果就是变量a和b都引用了相同的对象(指向了相同的内存空间)。这在Python中叫做共享引用——多个变量名引用了同一个对象。

如果再来一条语句

>>> a = 'spam'

会怎么样?

变量a引用了由常量表达式‘spam’所创建的新对象,但是变量b仍然引用原始的对象3,因为这个赋值运算改变的不是对象3,它仅仅改变了变量a的指向,变量b并没有发生改变。

在Python中,变量总是一个指向对象的指针,而不是可改变的内存区域的标签(比如C语言中的变量)。给一个变量赋一个新值,并不是修改了原始的对象,而是让这个变量去引用完全不同的一个对象。

注意:当可变的对象以及原处的改变进入这个场景,上述情形会有某种改变。

共享引用和在原处修改(Shared References and In-Place Changes)

有一些对象和操作确实会在原处改变对象。例如,在一个列表中通过偏移进行赋值,这确实会改变这个列表对象,而不是生成一个新的列表对象。对于支持这种在原处修改的对象,共享引用的时候一定要小心,因为对一个变量的修改会影响其他变量。

请看下面的语句:

>>> L1 = [2, 3, 4]
>>> L2 = L1

L1 是一个包含了对象2、3、4的列表。列表中的元素是通过他们的位置进行读取的,所以L1[0]引用对象2. 当然,列表自身也是对象,就像整数和字符串一样。在运行了上面两行语句后,L1和L2引用了相同的对象。

现在加上第3行:

>>> L1 = [2, 3, 4]
>>> L2 = L1
>>> L1[0] = 24

我们看一下L1和L2的值:

>>> L1
[24, 3 ,4]
>>> L2
[24, 3 ,4]

在这里,没有改变L1,改变了L1所引用的对象的一个元素,这类修改会覆盖列表对象中的某部分。因为这个列表对象同时被L1和L2引用,所以在原处修改不仅仅会影响L1,也会影响L2。虽然我们没有改变L2,但是它的值将发生变化。

如果你不想要这样的结果,那么需要拷贝对象,而不是创建引用。有很多拷贝列表的办法,最简单的办法是从头到尾的切片。

>>> L1 = [2, 3, 4]
>>> L2 = L1[:]
>>> L1[0] = 24
>>> L1
[24, 3, 4]
>>> L2
[2, 3, 4]

这里,对L1的修改不会影响L2,因为L2引用的是L1所引用对象的一个拷贝。也就是说,L1和L2指向了不同的内存区域。

共享引用和相等

>>> x = 42
>>> x = 'shrubbery'

因为Python缓存并复用了小的整数和小的字符串,执行完这两行代码后,对象42也许不会被回收;相反地,它可能仍被保存在一个系统表中,等待下一次你的代码生成另一个42来重复利用。尽管这样,大多数种类的对象都会在不被引用的时候马上回收。

在Python中有2种不同的方法去检查两个变量是否相等。

>>> L = [1, 2, 3]
>>> M = L                 # M and L reference the same object
>>> L == M                # Same values
True
>>> L is M                # Same objects
True

==操作符测试两个被引用的对象是否有相同的值,这种方法往往在Python中用作相等的检查。

is操作符用来检查对象的同一性。如果两个变量名都指向同一个对象,则会返回 True,所以这是一种更严格的相等测试。

实际上,is只是比较实现引用的指针,所以这是一种检测共享引用的方法。如果变量名指向不同的对象,就算这两个对象的值相等,也会返回 False.

例如:

>>> L = [1, 2, 3]
>>> M = [1, 2, 3]         # M and L reference different objects
>>> L == M                # Same values
True
>>> L is M                # Different objects
False

如果对小的数字进行类似测试:

>>> X = 42
>>> Y = 42                # Should be two different objects
>>> X == Y
True
>>> X is Y                # Same object anyhow: caching at work!
True

按理来说,第3~4行是可以理解的,因为两个对象的值一样;但是第5~6行就让人匪夷所思了,X引用的42和Y引用的42本来是2个对象,应该输出False才对,不过,因为小的整数和字符串被缓存并复用了,所以is告诉我们X和Y引用了同一个对象。

实际上,你可以用sys模块中的getrefcount函数查询对象的被引用次数。例如,我们查一下整数1被引用的次数:

>>> import sys
>>> sys.getrefcount(1)
812

这种对象缓存和复用的机制与代码是没有关系的。Python这样做是为了提高执行速度。

【End】

参考资料

《Python学习手册(第4版)》,机械工业出版社

Python学习之共享引用相关推荐

  1. Python学习教程:Python增强赋值及共享引用注意事项

    Python学习教程:Python增强赋值及共享引用注意事项 概述 Python中的增强赋值是从C语言中借鉴出来的,所以这些格式的用法大多和C一致,本身就是对表达式的简写,即二元表达式和赋值语句的结合 ...

  2. Python学习之变量、对象和引用

    Python学习之变量.对象和引用 文章目录 Python学习之变量.对象和引用 问题的引出 变量创建 变量类型 变量使用 动态类型 类型属于对象,而不是变量 对象的垃圾收集 参考资料 问题的引出 当 ...

  3. python学习高级篇(part9)--对象的引用计数

    学习笔记,仅供参考,有错必纠 文章目录 python 学习高级篇 类对象的特殊方法之`__str__()` 类对象的特殊方法之`__new__()` 对象的引用计数 什么是引用计数 对象的引用计数加1 ...

  4. python学习笔记4(对象/引用;多范式; 上下文管理器)

    python学习笔记4(对象/引用:多范式; 上下文管理器) ### Python的强大很大一部分原因在于,它提供有很多已经写好的,可以现成用的对象 21. 动态类型:对象/引用 对象和引用: 对象是 ...

  5. python赋值语句(解包赋值、多目标赋值及共享引用)

    python赋值语句(解包赋值.多目标赋值及共享引用) 序列解包赋值语句,赋值一系列整数给一组变量 red,green,blue=range(3) red,blue #(0, 2) 元组赋值语句在循环 ...

  6. python学习手册条件-Python学习手册(第4版)pdf

    Python学习手册(第4版) 内容简介 <Python学习手册(第4版)>学习Python的主要内建对象类型:数字.列表和字典.使用Python语句创建和处理对象,并且学习Python的 ...

  7. python学习手册中文版免费下载-Python学习手册

    Python学习手册第4 版将帮助你使用Python快速实现这一点,不管你是编程新手还是Python初学者.本书是易于掌握和自学的教程,根据作者Python专家Mark Lutz的著名培训课程编写而成 ...

  8. python学习手册中文版免费下载-Python学习手册 第三版

    <Python学习手册(第3版)>讲述了:Python可移植.功能强大.易于使用,是编写独立应用程序和脚本应用程序的理想选择.无论你是刚接触编程或者刚接触Python,通过学习<Py ...

  9. python学习手册中文版免费下载-Python学习手册(第3版)

    <Python学习手册(第3版)>为机械工业出版社出版. 目录 前言 第一部分 使用入门第1章 问答环节 人们为何使用Python 软件质量 开发者效率 Python是"脚本语言 ...

最新文章

  1. 【Flutter】JSON 模型转换 ( JSON 序列化工具 | JSON 手动序列化 | 根据 JSON 编写 Dart 模型类 | 在线自动根据 JSON 转换 Dart 类 )
  2. PyTorch基础(12)-- torch.nn.BatchNorm2d()方法
  3. 从 SAP WebIDE 里向Github 发起 push 的错误消息 - Git result: REJECTED_NONFASTFORWARD
  4. java -uf_Java如何快速修改Jar包里的文件内容
  5. Windows10最新MySQL8.0.23安装教程(超级详细)
  6. 在Blazor中构建数据库应用程序——第4部分——UI控件
  7. App后台开发运维和架构实践学习总结(2)——RESTful API设计技巧
  8. Linux 命令(115)—— rev 命令
  9. 外星人进化_外星人真的比人类强大吗?科学家给出几种猜想,你认同吗?
  10. 定位相关MATLAB仿真代码与在线MATLAB仿真平台
  11. c++实现通讯录制作
  12. 分布式数据库实战第三节 分布式数据库引擎、索引和事务
  13. 卓有成效的管理者—第四章 如何发挥人的长处
  14. 基于单片机的智能小区安防系统的设计
  15. 无码系列5.1 代码重构 消除重复代码
  16. flash插件+linux,Linux下的flash插件
  17. 新大陆物联网开发-物联网竞赛-物联网开发中必须要知道的协议-单片机嵌入式开发
  18. 【Matlab风电功率预测】EMD优化LSTM风电功率预测【含源码 1402期】
  19. 3d人物+衣服快速建模-makehuman
  20. java类和对象 壁虎_Java-基础篇(类和对象)

热门文章

  1. NYOJ 305 表达式求值
  2. NYOJ 1186 心理阴影(两个圆环的相交面积)
  3. BNUOJ 34978 汉诺塔
  4. 正则化与特征稀疏,过拟合
  5. Objective-c之NSCopying
  6. HTML5开发 桌面提醒功能
  7. 系统安装操作优化:chapter5 安装驱动程序与检测电脑
  8. C++输入输出流进制转换
  9. Android app集成Google Map方法
  10. USTC English Club Note20171012(4)