copy.copy在Python中与赋值操作有何不同?

10
我遇到了一段代码,乍一看似乎毫无意义。但我意识到这可能有一些未知的影响,因为Python不是我最熟悉的语言。
import copy
node = copy.copy(node)

阅读copy文档,其内容为:

copy.copy(x) 返回x的浅层拷贝。

浅层拷贝会构造一个新的复合对象,并尽可能地将原始对象中找到的对象的引用插入其中。

  1. 这段代码是否有作用?它正在从场景对象列表中获取节点。 它只创建了类的根级别的拷贝,因此可以更改变量(名称)但不影响列表中的原始节点吗? 节点类包含多个节点子类。

  2. copy.copy(node)node = node 有何不同?一种是构建一个新对象,而另一种只是简单地指向同一个对象吗?

3个回答

16

赋值运算符(=)只会创建一个指向对象的引用,并将创建一个新的变量引用相同的内存地址。

复制操作将在内存中创建一个新对象,然后将变量分配给它。

例如:

import copy

node = [0, 1]
node2 = node
node3 = copy.copy(node)

node2.append(5)

print(node)
print(node2)
print(node3)

输出:

[0, 1, 5]
[0, 1, 5]
[0, 1]

10

所有Python变量都是对内存中某些对象的绑定。

  1. 这段代码有什么作用吗?

有作用,它实际上会在内存中创建一个新的对象和一个新的名称。

  1. copy.copy(node)node = node有何不同?

通过赋值,你得到了相同对象的不同名称。 因此,如果你需要一份拷贝,应该使用shallowdeep copy。

例如:

>>> x = [1]
>>> id(x)
35964488
>>> y = x
>>> id(y)
35964488
>>> z = x[:]
>>> id(z)
35964768

所以xy具有相同的id,而z则不同。

这里也一样:

>>> import copy
>>> c = copy.copy(x)
>>> id(c)
35985168
>>> id(x)
35964488

关于 shallowdeep 复制的说明:

浅复制和深复制之间的区别仅涉及复合对象(包含其他对象,如列表或类实例的对象):

浅复制构造一个新的复合对象,然后(在尽可能的范围内)插入对原始对象中找到的对象的引用。

深复制构造一个新的复合对象,然后递归地将原始对象中找到的对象的副本插入其中。


4

首先,在Python中有两种类型的对象:可变和不可变。例如,您有一个列表(列表是可变的):

>>> a = [1,2]
>>> b = a
>>> b[0] = 3
>>> a
[3, 2]

但是,如果您使用简单复制 - 改变b的方式不会影响a:
>>> import copy
>>> b = copy.copy(a)
>>> a
[3, 2]
>>> b
[3, 2]
>>> b[0] = 4
>>> b
[4, 2]
>>> a
[3, 2]

还有一点需要注意:如果a由其他可变对象组成,则必须使用copy.deepcopy()来完全复制该对象,对其进行更改不会影响a


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接