Python语言中的引用和拷贝
2016-05-24 20:41
211 查看
本文对Python语言中的引用和拷贝的概念进行一个梳理。Python中赋值就是引用操作,而拷贝又分为浅拷贝、深拷贝两种方式。
下面我们来了解一下。
说明:
从例子中可看到,a的值的变化会导致b的值也会变化,因为他们是同一个对象,共享同一块内存地址,b是a的引用。
判断两个变量是否是同一个对象的方法是用is,返回True则代表两个变量是同一个对象。
总结:
赋值是将一个对象的地址赋值给一个变量,让变量指向该地址( 旧瓶装旧酒 )。
说明:
通过例子可以看到通过copy模块的copy方法,根据对象a生成了一个新对象b,这一点可以通过is表达式的结果证明。
a.append(‘c’)之后,发现a和b的值不一样了,这是因为a和b指向两个不同的地址。对a的值的修改不会影响b的值。
但是a[0].append(3)之后,a[0]和b[0]却是一样的。这就是浅拷贝的效果。因为a[0] 和b[0]还是指向同一个地址。
总结:
浅拷贝是在另一块地址中创建一个新的变量或容器,但是容器内的元素的地址均是源对象的元素的地址的拷贝。也就是说新的容器中指向了旧的元素( 新瓶装旧酒 )
还是以上面的例子为例。
说明:
由于b是a的深拷贝,所以a对象和b对象的内存地址不同,a对象和b对象包含的底层对象(a[0]a[1]b[0]b[1])内存地址也不同。
对a对象的值的改变不会影响b对象的值,对a对象的底层对象的值的改变也不会影响b的底层对象的值。
总结:
深拷贝是在另一块地址中创建一个新的变量或容器,同时容器内的元素的地址也是新开辟的,仅仅是值相同而已,是完全的副本。也就是说( 新瓶装新酒 )。
下面我们来了解一下。
1、引用
python中赋值符号“=”两边的对象是同一个对象,左边的对象可以看成是右边对象的一个引用。举例:>>> a=[1,2,'a','b'] >>> b=a >>> a [1, 2, 'a', 'b'] >>> b [1, 2, 'a', 'b'] >>> a.append('c') >>> a [1, 2, 'a', 'b', 'c'] >>> b [1, 2, 'a', 'b', 'c'] >>> a is b True
说明:
从例子中可看到,a的值的变化会导致b的值也会变化,因为他们是同一个对象,共享同一块内存地址,b是a的引用。
判断两个变量是否是同一个对象的方法是用is,返回True则代表两个变量是同一个对象。
总结:
赋值是将一个对象的地址赋值给一个变量,让变量指向该地址( 旧瓶装旧酒 )。
2、拷贝
对象的拷贝是根据源对象生成一个新的对象,占用不同的内容存空间。一个对象值的变化,不会影响另外一个对象的值。拷贝又分潜拷贝和深拷贝。2.1、潜拷贝
python中的copy模块可以实现对象的浅拷贝。什么是浅拷贝?举个例子来说明:>>> import copy >>> a=[[1,2],['a','b']] >>> b=copy.copy(a) >>> b is a >>> False >>> a.append('c') >>> a [[1, 2], ['a', 'b'], 'c'] >>> b [[1, 2], ['a', 'b']] >>> a[0].append(3) >>> a [[1, 2, 3], ['a', 'b'], 'c'] >>> b [[1, 2, 3], ['a', 'b']] >>> a[0] is b[0] >>> True
说明:
通过例子可以看到通过copy模块的copy方法,根据对象a生成了一个新对象b,这一点可以通过is表达式的结果证明。
a.append(‘c’)之后,发现a和b的值不一样了,这是因为a和b指向两个不同的地址。对a的值的修改不会影响b的值。
但是a[0].append(3)之后,a[0]和b[0]却是一样的。这就是浅拷贝的效果。因为a[0] 和b[0]还是指向同一个地址。
总结:
浅拷贝是在另一块地址中创建一个新的变量或容器,但是容器内的元素的地址均是源对象的元素的地址的拷贝。也就是说新的容器中指向了旧的元素( 新瓶装旧酒 )
2.2、深拷贝
python的copy模块的deepcopy函数可以实现深拷贝。还是以上面的例子为例。
>>> import copy >>> a=[[1,2],['a','b']] >>> b=copy.deepcopy(a) >>> a is b False >>> a[0] is b[0] False >>> a.append('c') >>> a [[1, 2, 3], ['a', 'b'], 'c'] >>> b [[1, 2], ['a', 'b']] >>> a[0].append(3) >>> a [[1, 2, 3], ['a', 'b']] >>> b [[1, 2], ['a', 'b']]
说明:
由于b是a的深拷贝,所以a对象和b对象的内存地址不同,a对象和b对象包含的底层对象(a[0]a[1]b[0]b[1])内存地址也不同。
对a对象的值的改变不会影响b对象的值,对a对象的底层对象的值的改变也不会影响b的底层对象的值。
总结:
深拷贝是在另一块地址中创建一个新的变量或容器,同时容器内的元素的地址也是新开辟的,仅仅是值相同而已,是完全的副本。也就是说( 新瓶装新酒 )。
相关文章推荐
- python爬虫
- Python Skelve 库
- Python Skelve 库
- python爬虫
- 也谈 Python 的中文编码处理
- Python实现欧拉计划27题
- python编程中在ubuntu中安装虚拟环境及环境配置
- python爬虫模块安装
- Python中exec的使用
- python多版本共存问题
- python 中time.sleep没有作用
- Python Tricks(十三)—— 欧几里得算法
- Python读取中文txt文件错误:UnicodeEncodeError: 'gbk' codec can't encode character
- Python Tricks(十二)—— 有理数的加法
- 简明 Python 教程
- IPython 与 Jupyter
- BZOJ 1213 Python... 二分+高精度
- 用PYTHON写一个应用程序并发布exe
- Python的for和break循环结构中使用else语句的技巧
- python类的静态方法和类方法区别