python模块 - copy模块

落日映苍穹つ 2022-08-08 12:58 428阅读 0赞

http://[blog.csdn.net/pipisorry/article/details/45830941][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到额外的空间中。

  1. a = [1, 2, [3, 4]]
  2. b = a
  3. b[2][0] = 100
  4. b[1] = 22
  5. print(a)
  6. 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中没有引用其它对象,那么浅拷贝就和深拷贝一样一样了。

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

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

示例3

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

  1. a = [1, 3, [2, 3]]
  2. b = a[:]
  3. b[2][0] = 1999
  4. b[1] = 2
  5. print(b)
  6. 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 都指向同一个对象。

1489720931-7116-4AQC6.png

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

1489720930-6827-Vtk4m.png

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

1489720930-5882-BO4qO.png

皮皮blog

改变copy的默认行为

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

class CopyObj(object):
def __repr__(self):
return “CopyObj”

  1. def \_\_copy\_\_(self):
  2. 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]

发表评论

表情:
评论列表 (有 0 条评论,428人围观)

还没有评论,来说两句吧...

相关阅读

    相关 python模块介绍_Python模块介绍

    简介 你已经学习了如何在你的程序中定义一次函数而重用代码。如果你想要在其他程序中重用很多函数,那么你该如何编写程序呢?你可能已经猜到了,答案是使用模块。模块基本上就是一个包含

    相关 python模块系列之 - copy

          在python中当定义完或者对一个变量完成赋值以后,在内存中就开辟了一块空间来存储对象。如果要将该对象复制一份给另一个对象就要用到copy模块。       在p