• copy.deepcopy
千次阅读
2021-07-04 00:10:15

## 1、浅copy时，1级的值和个数永远不会变化，但是如果1级不是具体的值，是集合、列表等时2级的子值会变化

2、深deepcopy时，b则会有自己的独立空间，不会再受a任何影响

## 一个例子就搞清楚

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import copy   a = [1, 2, 3, 4, ['a', 'b']] #原始对象   b = a #赋值，传对象的引用   c = copy.copy(a) #对象拷贝，浅拷贝   d = copy.deepcopy(a) #对象拷贝，深拷贝       a.append(5) #修改对象a   a[4].append('c') #修改对象a中的['a', 'b']数组对象       print 'a = ', a   print 'b = ', b   print 'c = ', c   print 'd = ', d   输出结果：  a = [1, 2, 3, 4, ['a', 'b', 'c'], 5]  b = [1, 2, 3, 4, ['a', 'b', 'c'], 5]  c = [1, 2, 3, 4, ['a', 'b', 'c']]  d = [1, 2, 3, 4, ['a', 'b']]

也可以这么理解，浅拷贝只引用了一级对象
深拷贝很容易理解，可以理解为完全独立的两个东西了

更多相关内容
• copy（）跟着原来的对象变 deepcopy（）则是一个新的对象，跟之前没关系

copy（）跟着原来的对象变
deepcopy（）则是一个新的对象，跟之前没关系

展开全文
• I have been using this copy method for quite a while, in lots of classes that needed it.class population (list):def __init__ (self):passdef copy(self):return copy.deepcopy(self)It has suddenly started...

I have been using this copy method for quite a while, in lots of classes that needed it.

class population (list):

def __init__ (self):

pass

def copy(self):

return copy.deepcopy(self)

It has suddenly started producing this error:

File "C:\Python26\lib\copy.py", line 338, in _reconstruct

state = deepcopy(state, memo)

File "C:\Python26\lib\copy.py", line 162, in deepcopy

y = copier(x, memo)

File "C:\Python26\lib\copy.py", line 255, in _deepcopy_dict

y[deepcopy(key, memo)] = deepcopy(value, memo)

File "C:\Python26\lib\copy.py", line 189, in deepcopy

y = _reconstruct(x, rv, 1, memo)

File "C:\Python26\lib\copy.py", line 323, in _reconstruct

y = callable(*args)

File "C:\Python26\lib\copy_reg.py", line 93, in __newobj__

return cls.__new__(cls, *args)

TypeError: object.__new__(generator) is not safe, use generator.__new__()

>>>

the lines which include the references to lines 338, 162, 255, 189 were repeated quite a few times before the 'line 338' that I copied here.

解决方案

Are you cloning a generator? Generators can't be cloned.

Copying answer by Gabriel Genellina here:

There is no way of "cloning" a generator:

py> g = (i for i in [1,2,3])

py> type(g)()

Traceback (most recent call last):

File "", line 1, in

TypeError: cannot create 'generator' instances

py> g.gi_code = code

Traceback (most recent call last):

File "", line 1, in

py> import copy

py> copy.copy(g)

Traceback (most recent call last):

...

TypeError: object.__new__(generator) is not safe, use generator.__new__()

py> type(g).__new__

You can do that with a generator function because it acts as a "generator

factory", building a new generator when called. Even using the Python C

API, to create a generator one needs a frame object -- and there is no way

to create a frame object "on the fly" that I know of :(

py> import ctypes

py> PyGen_New = ctypes.pythonapi.PyGen_New

py> PyGen_New.argtypes = [ctypes.py_object]

py> PyGen_New.restype = ctypes.py_object

py> g = (i for i in [1,2,3])

py> g2 = PyGen_New(g.gi_frame)

py> g2.gi_code is g.gi_code

True

py> g2.gi_frame is g.gi_frame

True

py> g.next()

1

py> g2.next()

2

g and g2 share the same execution frame, so they're not independent. There

is no easy way to create a new frame in Python:

py> type(g.gi_frame)()

Traceback (most recent call last):

File "", line 1, in

TypeError: cannot create 'frame' instances

One could try using PyFrame_New -- but that's way too magic for my taste...

展开全文
• I am trying to initialize a list of lists representing a 3x3 array:import copym = copy.deepcopy(3*[3*[0]])print(m)m[1][2] = 100print(m)and the output is:[[0, 0, 0], [0, 0, 0], [0, 0, 0]][[0, 0, 100], ...

I am trying to initialize a list of lists representing a 3x3 array:

import copy

m = copy.deepcopy(3*[3*[0]])

print(m)

m[1][2] = 100

print(m)

and the output is:

[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

[[0, 0, 100], [0, 0, 100], [0, 0, 100]]

which is not what I expected since the last elements of each row are shared! I did get the result I need by using:

m = [ copy.deepcopy(3*[0]) for i in range(3) ]

but I don't understand why the first (and simpler) form does not work. Isn't deepcopy supposed to be deep?

解决方案

The problem is that deepcopy keeps a memo that contains all instances that have been copied already. That's to avoid infinite recursions and intentional shared objects. So when it tries to deepcopy the second sublist it sees that it has already copied it (the first sublist) and just inserts the first sublist again. In short deepcopy doesn't solve the "shared sublist" problem!

To quote the documentation:

Two problems often exist with deep copy operations that don’t exist with shallow copy operations:

Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop.

Because deep copy copies everything it may copy too much, such as data which is intended to be shared between copies.

The deepcopy() function avoids these problems by:

keeping a “memo” dictionary of objects already copied during the current copying pass; and

letting user-defined classes override the copying operation or the set of components copied.

(emphasis mine)

That means that deepcopy regards shared references as intention. For example consider the class:

from copy import deepcopy

class A(object):

def __init__(self, x):

self.x = x

self.x1 = x[0] # intentional sharing of the sublist with x attribute

self.x2 = x[1] # intentional sharing of the sublist with x attribute

a1 = A([[1, 2], [2, 3]])

a2 = deepcopy(a1)

a2.x1[0] = 10

print(a2.x)

# [[10, 2], [2, 3]]

Neglecting that the class doesn't make much sense as is it intentionally shares the references between its x and x1 and x2 attribute. It would be weird if deepcopy broke those shared references by doing a separate copy of each of these. That's why the documentation mentions this as a "solution" to the problem of "copy too much, such as data which is intended to be shared between copies.".

Back to your example: If you don't want to have shared references it would be better to avoid them completely:

m = [[0]*3 for _ in range(3)]

In your case the inner elements are immutable because 0 is immutable - but if you deal with mutable instances inside the innermost lists you must have to avoid the inner list multiplication as well:

m = [[0 for _ in range(3)] for _ in range(3)]

展开全文
• 某次做实验,为了完全复制一个新模型,使用copy.deepcopy model2 = copy.deepcopy(model1) 这样复制后model2中的param.grad都是None,原因是deepcopy 只复制了数值,并没有对相关属性做对应的copy
• copy.deepcopy()使我们印象中常见的copy，即copy一个对象，改变原对象，copy对象的值不变。 copy.copy() 就像是快捷方式的copy, 即改变原对象，copy对象随之改变。
• 在深度学习的训练和测试过程中，可能会涉及到对同一个模型进行多次拷贝，分别进行不同的训练或者加载不同的checkpoint参数，这时候不能使用等号进行简单的拷贝，而是需要使用copy.deepcopy()进行深拷贝。 例如： ...
• python中对于对象的拷贝分为浅拷贝(copy)和深拷贝(deepcopy)两种方式。其中浅拷贝由“=”完成。而深拷贝由copy模块中deepcopy()函数担任。 浅拷贝和深拷贝的区别是： 浅拷贝只是将原对象在内存中引用地址拷贝过来了...
• title: Python 中谨慎使用 copy.deepcopy()>在一次做 Benchmark 的时候，发现无论如何调代码，最后总是不尽人意，之后用 `p
• [1, 2, [3, [4, 5]]] b = a # 直接赋值: 引用对象，原始对象的最外层到最内层对象均被引用 c = copy.copy(a) # 浅拷贝：原始对象的最外层对象深拷贝，除外层的所有层对象直接赋值 d = copy.deepcopy(a) # 深拷贝，...
• 今天面试问到一个题，copy.copy()和copy.deepcopy()有什么区别？ 在结束后查询了很多博主，各说其词，各不相同，各有千秋，我综合一下他们的所有说法，得出一下结论： 不论是深拷贝还是浅拷贝，只要是针对不可变的...
• While doing that, I stumbled on this puzzle: new_obj = copy.deepcopy(my_obj) function_that_uses_my_new_obj(new_obj) throws: function_that_uses_my_new_obj(new_obj) RuntimeError: Internal C++ object ...
• coopy.deepcopy()函数是一个深复制函数。 所谓深复制，就是从输入变量完全复刻一个相同的变量，无论怎么改变新变量，原有变量的值都不会受到影响。 与等号赋值不同，等号复制类似于贴标签，两者实质上是同一段内存。...
• ## python copy.deepcopy()深入解读

千次阅读 多人点赞 2020-09-17 20:52:55
copy.deepcopy()的用法是将某一个变量的值赋值给另一个变量(此时两个变量地址不同)，因为地址不同，所以这两个变量互不干扰。 大家可以猜猜下面代码第四行输出什么值 a = [1, 2, 3] d = a # a和d的地址相同， 看第5...
• 1.python深浅拷贝和C++中含义不同 浅拷贝： copy.copy() 新的变量和原变量为同一个，改变其中一个值，另一个也会变 深拷贝： copy.deepcopy() 独立的变量，互不干扰
• 介绍 deepcopy是用来进行深层复制的, 但是在实际中可能遇到, 复制一个对象后, 某些属性没了, 因此...deepcopy的文档: https://docs.python.org/3/library/copy.html """ def deepcopy(x, memo=None, _nil=[]): """Dee
• 源于： 功能类代码 – TxtSampleCluster.py 功能比较： ...copy.deepcopy()是深拷贝，会拷贝对象及其子对象。 import copy List1 = ['1', '2', 3, 'a', ['b', 'c']] List2 = List1 # 将List1赋给L...
• 在python中deepcopy一个自定义的对象时报错 maximum recursion depth exceeded while calling a Python object 而且在本机运行并不会报错，在服务器上运行才会报错。 解决 参考: ...
• 列表的深拷贝和浅拷贝 因为列表的赋值只是“引用“”，实际上还是指向同一个内存地址 l1= [1,2] l2 = l1 print(id(l1),id(l2)) >...当要复制出一份完全相同的变量，需要...c2 = copy.deepcopy(l) print(l) pri..
• framenum = len(os.listdir(video_path)) begin_point = 1 end_point = framenum sample = { 'video': video_path, 'segment': [begin_point, end_point], 'n_... 16+ 1), step): sample_i = copy.deepcopy(sample)
• copy.copy()是浅复制，copy.deepcopy()是深复制 copy()之后的对象与原对象之间存在联系，可能会出现其中一个改变另外一个也改变的情况： c=['a','b','d','f','&lt;eos&gt;',[1,24]] d=copy.copy(c) d[5]....
• 当有自定义的class继承了dict时，在使用copy.deepcopy便需要。
• 使用copy模块中的deepcopy方法深度克隆某一个对象，如果方法使用不当那么就会出现各种各样的问题，例如can't pickle module objects error
• copy.copy() 元组和列表调用这个方法效果也不一样。 元组的效果： a = [1,2,3] b = [4,5,6] c = (a,b) e = copy.copy(c) ...copy.deepcopy() 这个是深拷贝，并且是递归的形式拷贝的 元组的效果...
• 在Python中对象的赋值其实就是对象的引用。 当创建一个对象a，把它赋值给另一个变量b的时候，python并没有拷贝a这...import copy a=[1,2,3] b=a #赋值，传对象的引用 b.append(1) print(a) print(b) print(id(a)...
• copy.deepcopy() 方法 例子 # 因为可变对象导致结果不正确 def generate_dataset(dataset, shot, way, error_num): data = dataset.reshape(shot, way, 3, 84, 84) # [25]->[5,5] data_ori = dataset....

...