Python学习笔记之拷贝

来源:互联网 发布:人工智能计算器旧版本 编辑:程序博客网 时间:2024/06/03 21:31

浅拷贝,深拷贝。我一听到这两个词就有点儿懵逼。怎么copy也分深浅了!??

为了弄清这浅拷贝和深拷贝到底是何方神圣,我仔细的将书本内容进行研读,终于理解了这两种拷贝的“水深”

为了说明这个问题,我们来举个栗子

现在有那么一对夫妻要到银行开设他们两个人的银行账号。
我们先新建一个通用账号,名字叫person。
然后分别为他俩拷贝一份属于他们自己的账号。

>>> person = ['name', ['savings', 100.00]]>>> husband = person[:]   #切片复制>>> wife = list(person)   #利用工厂函数>>> [id(x) for x in person, husband, wife] #运用id()来显示每个对象的标识符[11826320, 12223552, 11850936]

好的我们现在已经将银行账号创建好了,他们初始情况下是有100元。而且这三个账号的是不同的(它们的对象标识符不同)

现在我们试着写上husband和wife的名字,并且命令丈夫从银行账户中取走50元。我们看看这时候银行账号会发生什么?!

>>> husband[0] = 'jack'>>> wife[0] = 'marry'>>> husband, wife(['jack', ['savings', 100.0]], ['marry', ['savings', 100.0]])>>> husband[1][1] = 50.00>>> husband,wife(['jack', ['savings', 50.0]], ['marry', ['savings', 50.0]])

jack取走了50元后,不仅jack的账号减少了50元,同时marry的账号也减少了50元。这说明这个银行账号是他们俩人的联合账户。

为什么呢?我们明明复制了两个账户,他们的标识符不一样,为什么修改了一个,另外一个的值也会被修改呢?
原来这里的复制只是创建了一个引用而已。这就是所谓的浅拷贝!!

浅拷贝:创建一个类型跟原对象一样的新对象,它的内容是原来对象元素的引用
也就是说,jack和marry拷贝的银行账户是不同的,但是存款却是他们俩人共有的。

以下几种方式能够创建浅拷贝:

  1. 完全切片操作[:]
  2. 利用工厂函数,比如list()、dict()等
  3. 使用copy模块的copy函数

看到这里,我们知道他们两个人的账号是因为浅拷贝,所以他们的账户金额是共享的。

那么又有一个问题出来了!

为什么他们的名字不共享呢?明明两个账户的内容都是联合账户的引用啊!?

原来是因为对象类型的不同。名字是不可变类型(字符串类型),账户是可变类型(列表类型)所以名字是新建的字符串对象,而账户金额是引用

PS:我来回顾一下那些是不可变类型。
1.数字 2.字符串 3.元祖(元祖中不包含列表)

现在我们要为这对夫妇创建他们的个人账户(不共享账户金额),这会儿应该怎么做呢?

答,深拷贝!!

>>> person = ['name', ['savings', 100.00]]>>> husband = person[:]   #切片复制>>> import copy>>> wife = copy.deepcopy(person)   #使用深拷贝>>> [id(x) for x in person, husband, wife] #运用id()来显示每个对象的标识符[11826320, 12223552, 11850936]>>> husband[0] = 'jack'>>> wife[0] = 'marry'>>> husband, wife(['jack', ['savings', 100.0]], ['marry', ['savings', 100.0]])>>> husband[1][1] = 50.00>>> husband,wife(['jack', ['savings', 50.0]], ['marry', ['savings', 100.0]])#husband和wife中 名字 和 账户金额 的对象标识符>>> [id(x) for x in huaband][12191712,11826280]>>> [id(x) for x in wife][12114080,12224792]

我们可以看到,运用深拷贝就可以创建个人账户了!

我们现在来总结一下
浅拷贝:浅拷贝中可变数据类型是拷贝对象的可变数据类型的引用,而不可变数据类型却是一个新对象
深拷贝:深拷贝中不管数据类型如何,拷贝后都会创建一个新对象

0 0
原创粉丝点击