Python语言中的引用和拷贝

来源:互联网 发布:期货模拟交易软件 编辑:程序博客网 时间:2024/05/01 06:55

本文对Python语言中的引用和拷贝的概念进行一个梳理。Python中赋值就是引用操作,而拷贝又分为浅拷贝、深拷贝两种方式。
下面我们来了解一下。

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 bTrue

说明:
从例子中可看到,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 bFalse>>> 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的底层对象的值。
总结:
深拷贝是在另一块地址中创建一个新的变量或容器,同时容器内的元素的地址也是新开辟的,仅仅是值相同而已,是完全的副本。也就是说( 新瓶装新酒 )。

0 0
原创粉丝点击