Python中实现变量赋值传递时的引用和拷贝方法


Posted in Python onApril 29, 2018

iamlaosong文

曾经看到这样一个问题,一个字典中的元素是列表,将这个列表元素赋值给一个变量,然后修改这个列表中元素的值,结果发现,字典中那个列表也同样修改了。

那个问题如下:

dict = {'a':[1,2,3,4,5],'b':2} 
x = dict['a'] 
for i in range(5): 
  x[i] = 0 
print(dict['a'])

程序运行结果如下:

[0, 0, 0, 0, 0]

这儿涉及到Python赋值到底是引用还是拷贝一份的问题,即赋值时是传值还是传址。上面问题是将“a”的值赋给了x出现了上述情况,如果是将“b”的值赋给了x,当我们修改x的值时,字典dict的值并不受影响。

>>> dict = {'a':[1,2,3,4,5],'b':2} 
>>> x = dict['b'] 
>>> x 
2 
>>> x=x+3 
>>> x 
5 
>>> dict 
{'a': [1, 2, 3, 4, 5], 'b': 2} 
>>>

那么问题来了,变量赋值传递时什么情况下是传值(拷贝),什么情况下是传址(引用)呢?

1、直接拷贝

当我们不知道是引用还是拷贝的情况下,可以显式的拷贝。比如字典对象本身都具有拷贝的方法:

x=dict.copy()

没有拷贝方法的对象,也是可以拷贝的。这儿我们引入一个深拷贝的概念,深拷贝——即python的copy模块提供的一个deepcopy方法。深拷贝会完全复制原变量相关的所有数据,在内存中生成一套完全一样的内容,在这个过程中我们对这两个变量中的一个进行任意修改都不会影响其他变量。还是上面的代码,如果改成如下:

import copy 
dict = {'a':[1,2,3,4,5],'b':2} 
x = copy.deepcopy(dict['a']) 
for i in range(5): 
  x[i] = 0 
print(dict['a'])

运行结果dict值不受影响。

除了深拷贝,copy模块还提供一个copy方法,称其为浅拷贝,对于简单的对象,深浅拷贝都是一样的,上面的词典对象的copy方法就是浅拷贝。

>>> dict
{'a': [8, 2, 3, 4, 5], 'b': 4}
>>> dd=copy.copy(dict)
>>> dd
{'a': [8, 2, 3, 4, 5], 'b': 4}
>>> dd['a'][0]=7
>>> dd
{'a': [7, 2, 3, 4, 5], 'b': 4}
>>> dict
{'a': [7, 2, 3, 4, 5], 'b': 4}
>>> ee=dict.copy()
>>> ee
{'a': [7, 2, 3, 4, 5], 'b': 4}
>>> ee['a'][0]=9
>>> ee
{'a': [9, 2, 3, 4, 5], 'b': 4}
>>> dict
{'a': [9, 2, 3, 4, 5], 'b': 4}
>>> ee['b']=5
>>> ee
{'a': [9, 2, 3, 4, 5], 'b': 5}
>>> dict
{'a': [9, 2, 3, 4, 5], 'b': 4}
>>>

浅拷贝时改变第一层次相互不受影响(上例中词典b值的修改),第二层次(上例中词典a的列表值修改)就相互影响了,改一个,其他跟着变。看看id吧:

>>> id(dict) 
20109472 
>>> id(dd) 
20244496 
>>> id(ee) 
20495072 
>>> id(dd['a']) 
20272112 
>>> id(ee['a']) 
20272112 
>>> id(dict['a']) 
20272112 
>>>

可见词典各个拷贝的id是不同的,但词典a值的id是相同的。如果我们需要真正意义的拷贝,就用深拷贝吧。

2、传递规则

Python赋值过程中不明确区分拷贝和引用,一般对静态变量的传递为拷贝,对动态变量的传递为引用。(注,对静态变量首次传递时也是引用,当需要修改静态变量时,因为静态变量不能改变,所以需要生成一个新的空间存储数据)。

字符串,数值,元组均为静态变量

列表,字典为动态变量。

变量有时比较复杂,存在组合现象,比如字典中包含列表,列表中包含字典,但赋值时,总是属于某个类型。如果实在不清楚状况,可以试验一下,用id()这个函数看看,如果是引用,两个变量指向的地址是相同的。例如:

>>> a=6 
>>> id(a) 
10413476 
>>> b=a 
>>> id(b) 
10413476 
>>> b=8 
>>> id(b) 
10413452 
>>>

修改变量b之前,a和b指向的地址是相同的,修改b后,地址就变了。

以上这篇Python中实现变量赋值传递时的引用和拷贝方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python命令行参数sys.argv使用示例
Jan 28 Python
跟老齐学Python之??碌某?? target=
Sep 12 Python
python实现无证书加密解密实例
Oct 27 Python
详解python实现读取邮件数据并下载附件的实例
Aug 03 Python
Python(Django)项目与Apache的管理交互的方法
May 16 Python
Python实现的读取/更改/写入xml文件操作示例
Aug 30 Python
Linux下python3.6.1环境配置教程
Sep 26 Python
Python监控服务器实用工具psutil使用解析
Dec 19 Python
Python 使用 environs 库定义环境变量的方法
Feb 25 Python
浅谈优化Django ORM中的性能问题
Jul 09 Python
python3实现将json对象存入Redis以及数据的导入导出
Jul 16 Python
jupyter notebook远程访问不了的问题解决方法
Jan 11 Python
分享一下Python数据分析常用的8款工具
Apr 29 #Python
Python随机函数random()使用方法小结
Apr 29 #Python
Python中py文件引用另一个py文件变量的方法
Apr 29 #Python
python实现类之间的方法互相调用
Apr 29 #Python
Python装饰器原理与简单用法实例分析
Apr 29 #Python
Python2.7 实现引入自己写的类方法
Apr 29 #Python
Python 实现引用其他.py文件中的类和类的方法
Apr 29 #Python
You might like
php将fileterms函数返回的结果变成可读的形式
2011/04/21 PHP
PHP编译安装时常见错误解决办法
2015/05/28 PHP
Yii模型操作之criteria查找数据库的方法
2016/07/15 PHP
谈谈从phpinfo中能获取哪些值得注意的信息
2017/03/28 PHP
PHP实现验证码校验功能
2017/11/16 PHP
javascript基础知识大集锦(一) 推荐收藏
2011/01/13 Javascript
json中换行符的处理方法示例介绍
2014/06/10 Javascript
基于javascript实现判断移动终端浏览器版本信息
2014/12/09 Javascript
详解jQuery UI库中文本输入自动补全功能的用法
2016/04/23 Javascript
JavaScript实现移动端滑动选择日期功能
2016/06/21 Javascript
分分钟玩转Vue.js组件
2016/10/25 Javascript
微信小程序实现滑动删除效果
2017/05/19 Javascript
微信小程序异步处理详解
2017/11/10 Javascript
react-router v4如何使用history控制路由跳转详解
2018/01/09 Javascript
基于Vue实现平滑过渡的拖拽排序功能
2019/06/12 Javascript
JS寄快递地址智能解析的实现代码
2020/07/16 Javascript
[45:34]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第一场 12.18
2020/12/19 DOTA
python使用webbrowser浏览指定url的方法
2015/04/04 Python
Python中用sleep()方法操作时间的教程
2015/05/22 Python
python爬虫的工作原理
2017/03/05 Python
深入理解Python3 内置函数大全
2017/11/23 Python
caffe binaryproto 与 npy相互转换的实例讲解
2018/07/09 Python
python 内置函数汇总详解
2019/09/16 Python
Python pandas自定义函数的使用方法示例
2019/11/20 Python
python实现用类读取文件数据并计算矩形面积
2020/01/18 Python
python求最大公约数和最小公倍数的简单方法
2020/02/13 Python
在Mac中配置Python虚拟环境过程解析
2020/06/22 Python
如何使用Django Admin管理后台导入CSV
2020/11/06 Python
python中uuid模块实例浅析
2020/12/29 Python
详解HTML5新增标签
2017/11/27 HTML / CSS
存储过程的优点有哪些
2012/09/27 面试题
党员个人查摆剖析材料
2014/10/16 职场文书
暑期社会实践个人总结
2015/03/06 职场文书
入党宣誓仪式主持词
2015/06/29 职场文书
《富饶的西沙群岛》教学反思
2016/02/16 职场文书
导游词之广东佛山(南风古灶)
2019/09/24 职场文书