我怎样才能在Python中创build一个对象的副本?
我想创build一个对象的副本。 我希望新对象拥有旧对象的所有属性(字段的值)。 但我想要有独立的对象。 所以,如果我改变新对象的字段的值,旧对象不应该受到影响。
看看copy.deepcopy()
函数。 它应该做你所需要的。 也有一个很好的解释,看看这个答案相关的问题。
我怎样才能在Python中创build一个对象的副本?
所以,如果我改变新对象的字段的值,旧对象不应该受到影响。
那么你的意思是一个可变的对象。
在Python 3中,列表会得到一个copy
方法(在2中,您将使用一个分片来创build副本):
>>> a_list = list('abc') >>> a_copy_of_a_list = a_list.copy() >>> a_copy_of_a_list is a_list False >>> a_copy_of_a_list == a_list True
浅的副本
浅拷贝只是最外层容器的拷贝。
list.copy
是一个浅拷贝:
>>> list_of_dict_of_set = [{'foo': set('abc')} ... ] >>> list_of_dict_of_set = [{'foo': set('abc')}] >>> lodos_copy = list_of_dict_of_set.copy() >>> lodos_copy[0]['foo'].pop() 'c' >>> lodos_copy [{'foo': {'b', 'a'}}] >>> list_of_dict_of_set [{'foo': {'b', 'a'}}]
你不会得到一个内部对象的副本。 它们是同一个对象 – 所以当它们发生变异时,变化显示在两个容器中。
深拷贝
深拷贝是每个内部对象的recursion拷贝。
>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set) >>> lodos_deep_copy[0]['foo'].add('c') >>> lodos_deep_copy [{'foo': {'c', 'b', 'a'}}] >>> list_of_dict_of_set [{'foo': {'b', 'a'}}]
只有在原件中才有变化。
不可变的对象
不可变对象通常不需要被复制。 事实上,如果你尝试,Python会给你原来的对象:
>>> a_tuple = tuple('abc') >>> tuple_copy_attempt = a_tuple.copy() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'tuple' object has no attribute 'copy'
元组甚至没有复制方法,所以让我们尝试一下:
>>> tuple_copy_attempt = a_tuple[:]
但是我们看到这是同一个对象:
>>> tuple_copy_attempt is a_tuple True
类似的string:
>>> s = 'abc' >>> s0 = s[:] >>> s == s0 True >>> s is s0 True
对于frozensets,即使他们有一个copy
方法:
>>> a_frozenset = frozenset('abc') >>> frozenset_copy_attempt = a_frozenset.copy() >>> frozenset_copy_attempt is a_frozenset True
何时复制不可变对象
如果需要复制可变内部对象,则应该复制不可变对象。
>>> tuple_of_list = [], >>> copy_of_tuple_of_list = tuple_of_list[:] >>> copy_of_tuple_of_list[0].append('a') >>> copy_of_tuple_of_list (['a'],) >>> tuple_of_list (['a'],) >>> deepcopy_of_tuple_of_list = copy.deepcopy(tuple_of_list) >>> deepcopy_of_tuple_of_list[0].append('b') >>> deepcopy_of_tuple_of_list (['a', 'b'],) >>> tuple_of_list (['a'],)
正如我们所看到的,当副本的内部对象发生变化时,原始内容不会改变。