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. Java常用的集合类
  2. 菲律宾谋定农业大建特建构想 对话国际农民丰收节贸易会
  3. SAP CRM service contract和individual object
  4. hibernate.hbm2ddl.auto配置及意义
  5. kafka maven没有下载_Kafka 系列(三)——Kafka 生产者详解
  6. OrCAD Capture使用记录
  7. 修复ext4日志(jbd2)bug( Ext4 文件系统有以下 Bug)
  8. 网吧个性化系统的制作与优化(终极版)(转)
  9. PYTHON 获取淘宝服务器时间 显示在tkinter的UI
  10. SDU-nachos安装及初步编译
  11. android之在java代码引用res资源
  12. 按头安利!精品又实用的unity3D游戏素材看这里!
  13. ubuntu更改ip地址 网官 dns,使ubuntu的ip地址每次启动都是固定
  14. golang快速入门[3]-go语言helloworld
  15. 任正非、董明珠、曹德旺,中国实业三大网红!他们有个共同点:坚决不做一件事!
  16. 动漫人脸识别技术及数据集介绍
  17. Android bug日志/错误收集
  18. 数据中心解决方案之灾备方案设计(上)
  19. 活码二维码免费平台有哪些呢?
  20. js根据开始日期和相隔天数计算出结束日期

热门文章

  1. nyoj-205--求余数--(大整数取模)
  2. NYOJ 914 Yougth的最大化(二分搜索 + 贪心)
  3. Java(21)_ ^、|、运算符
  4. [CHM]果壳中的XAML(XAML in a Nutshell)
  5. vue3-network 无效
  6. Git学习笔记:如何删除GitHub上的项目
  7. Android自定义控件(特效二) 点击屏幕,根据所点击的位置绘制桃心
  8. /root/.bashrc与/etc/profile的异同
  9. ubuntu 搜索文件方法(find命令)
  10. Linux sem_init函数用法