python模块 - copy模块

http://blog.csdn.net/pipisorry/article/details/45830941

copy模块之浅拷贝与深拷贝

copy模块用于对象的拷贝操作。该模块只提供了两个主要的方法:copy.copy与copy.deepcopy,分别表示浅复制与深复制。

直接赋值,深拷贝和浅拷贝的区别

直接赋值:简单地拷贝对象的引用,两个对象的id相同。就是对象的引用(别名),就是给当前内存中的对象增加一个“标签”而已。通过使用内置函数 id() ,可以看出指向内存中同一个对象。

浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。即浅复制只复制对象本身,没有复制该对象所引用的对象。A shallow copy constructs a new compound object and then (to the extentpossible) inserts references into it to the objects found in the original.

深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。即创建一个新的组合对象,同时递归地拷贝所有子对象,新的组合对象与原对象没有任何关联。虽然实际上会共享不可变的子对象,但不影响它们的相互独立性。A deep copy constructs a new compound object and then, recursively, insertscopies into it of the objects found in the original.

浅拷贝和深拷贝的不同仅仅是对组合对象来说,所谓的组合对象就是包含了其它对象的对象,如列表,类实例。而对于数字、字符串以及其它“原子”类型,没有拷贝一说,产生的都是原对象的引用,所以两者就是一样的结果了。

 

直接赋值

直接赋值既不是浅拷贝也不是深拷贝!

>>> a = 3

>>> b = a

>>> b = 4

>>> a

3

>>> b

4

>>> 

对组合对象来说,赋值后两者完全一样,相当于视图(numpy),没有copy到额外的空间中。

a = [1, 2, [3, 4]]
b = a
b[2][0] = 100
b[1] = 22
print(a)
print(b)

[1, 22, [100, 4]]

[1, 22, [100, 4]]

两个列表就是同一个列表,没有任何copy。

皮皮blog

 

 

浅拷贝和深拷贝示例

浅拷贝shallow copy

字典的浅拷贝dict.copy()。

列表list的浅拷贝 assigning a slice of the entire list, copied_list = original_list[:];或者直接list1.copy()。

示例1

#coding=gbk
import copy
l1 = [1, 2, [3, 4]]
l2 = copy.copy(l1)
print l1
print l2
l2[2][0] = 50
print l1
print l2
#---- 结果 ----
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [50, 4]]
[1, 2, [50, 4]]

示例2

如果list中没有引用其它对象,那么浅拷贝就和深拷贝一样一样了。

a = [1, 2, 3]
b = a.copy()
b[0] = 333
print(b)
print(a)

[333, 2, 3]
[1, 2, 3]

示例3

真正了解浅拷贝/深拷贝的示例。

a = [1, 3, [2, 3]]
b = a[:]
b[2][0] = 1999
b[1] = 2
print(b)
print(a)

[1, 2, [1999, 3]]
[1, 3, [1999, 3]]

深拷贝deep copy

深复制,不仅复制对象本身,同时也复制该对象所引用的对象。

示例1

import copy
l1 = [1, 2, [3, 4]]
l2 = copy.deepcopy(l1)
print l1
print l2
l2[2][0] = 50
print l1
print l2
#---- 结果 ----
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [50, 4]]

皮皮blog

 

 

 

字典浅拷贝实例

 

浅拷贝:

>>>a = {1: [1,2,3]}
>>> b = a.copy()
>>> a, b
({1: [1, 2, 3]}, {1: [1, 2, 3]})
>>> a[1].append(4)
>>> a, b
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})

深度拷贝:

>>>import copy
>>> c = copy.deepcopy(a)
>>> a, c
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})
>>> a[1].append(5)
>>> a, c
({1: [1, 2, 3, 4, 5]}, {1: [1, 2, 3, 4]})

解析

1、b = a: 赋值引用,a 和 b 都指向同一个对象。

python模块 - copy模块_第1张图片

2、b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。

python模块 - copy模块_第2张图片

b = copy.deepcopy(a): 深度拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。

python模块 - copy模块_第3张图片

皮皮blog

 

 

改变copy的默认行为

在定义类的时候,通过定义__copy__和__deepcopy__方法,可以改变copy的默认行为。下面是一个简单的例子:

class CopyObj(object):
    def __repr__(self):
        return "CopyObj"
    
    def __copy__(self):
        return "Hello"
obj = CopyObj()
obj1 = copy.copy(obj)
print obj
print obj1
#---- 结果 ----
CopyObj
Hello

from:http://blog.csdn.net/pipisorry/article/details/45830941

ref: [copy — Shallow and deep copy operations]

 

你可能感兴趣的:(Python类,函数和模块)