如何在python中复制类实例? [英] How to copy a class instance in python?
问题描述
我想在python中复制一个类实例.我尝试了 copy.deepcopy
,但收到错误消息:
I would like to make a copy of a class instance in python. I tried copy.deepcopy
but I get the error message:
RuntimeError:目前,仅由用户(图形叶子)显式创建的变量支持Deepcopy协议
RuntimeError: Only Variables created explicitly by the user (graph leaves) support the deepcopy protocol at the moment
所以假设我有类似的东西:
So suppose I have something like:
class C(object):
def __init__(self,a,b, **kwargs):
self.a=a
self.b=b
for x, v in kwargs.items():
setattr(self, x, v)
c = C(4,5,'r'=2)
c.a = 11
del c.b
现在我想制作 c
的相同深层副本,有没有简单的方法?
And now I want to make an identical deep copy of c
, is there an easy way?
推荐答案
我基本上已经弄清楚了.我无法克服的唯一问题是,为所有类了解一组可接受的初始化参数( __ init __
的参数).所以我必须做以下两个假设:
I have mostly figured it out. The only problem which I cannot overcome is knowing an acceptable set of initialization arguments (arguments for __init__
) for all classes. So I have to make the following two assumtions:
1)我为类 C
设置了一组默认参数,我将其称为 argsC
.2) C
中的所有对象都可以使用空参数初始化.
1) I have a set of default arguments for class C
which I call argsC
.
2) All objects in C
can be initialized with empty arguments.
在这种情况下,我可以第一:从我要复制 c
的实例中初始化类 C
的新实例:
In which case I can
First:
Initialize a new instance of the class C
from it's instance which I want to copy c
:
c_copy = c.__class__(**argsC)
第二:遍历 c
的所有属性,并将属性 c_copy
设置为 c
Second:
Go through all the attributes of c
and set the attributes c_copy
to be a copy of the attributes of c
for att in c.__dict__:
setattr(c_copy, att, object_copy(getattr(c,att)))
其中 object_copy
是我们正在构建的函数的递归应用程序.
where object_copy
is a recursive application of the function we are building.
最后:删除 c_copy
中的所有属性,但不删除 c
中的所有属性:
Last:
Delete all attributes in c_copy
but not in c
:
for att in c_copy.__dict__:
if not hasattr(c, att):
delattr(c_copy, att)
将所有这些放在一起:
import copy
def object_copy(instance, init_args=None):
if init_args:
new_obj = instance.__class__(**init_args)
else:
new_obj = instance.__class__()
if hasattr(instance, '__dict__'):
for k in instance.__dict__ :
try:
attr_copy = copy.deepcopy(getattr(instance, k))
except Exception as e:
attr_copy = object_copy(getattr(instance, k))
setattr(new_obj, k, attr_copy)
new_attrs = list(new_obj.__dict__.keys())
for k in new_attrs:
if not hasattr(instance, k):
delattr(new_obj, k)
return new_obj
else:
return instance
因此,我们将所有内容放在一起:
So putting it all together we have:
argsC = {'a':1, 'b':1}
c = C(4,5,r=[[1],2,3])
c.a = 11
del c.b
c_copy = object_copy(c, argsC)
c.__dict__
{'a':11,'r':[[1],2,3]}
{'a': 11, 'r': [[1], 2, 3]}
c_copy.__dict__
{'a':11,'r':[[1],2,3]}
{'a': 11, 'r': [[1], 2, 3]}
c.__dict__
{'a':11,'r':[[1,33],2,3]}
{'a': 11, 'r': [[1, 33], 2, 3]}
c_copy.__dict__
{'a':11,'r':[[1],2,3]}
{'a': 11, 'r': [[1], 2, 3]}
这是期望的结果.如果可以的话,它使用 deepcopy
,但是对于可能引发异常的情况,它可以不这样做.
Which is the desired outcome. It uses deepcopy
if it can, but for the cases where it would raise an exception, it can do without.
这篇关于如何在python中复制类实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!