marsh
marsh

Reputation: 2730

Is copy.copy different from assignment in python

I have run across a piece of code that at first glance seems pointless. But I realize that this could have some unknown implications that I am not aware of as Python is not my most known language.

import copy
node = copy.copy(node)

Reading the documentation of copy it says that

copy.copy(x) Return a shallow copy of x.

A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

  1. Does this code do anything? The node that it is copying is being taken from a scene list of objects. Is it creating a copy of just the root level of the class so it can change variables (name) but not effect the original in the list? The node class contains several node children.

  2. How does copy.copy(node) differ from node = node Is one constructing a new object while the other is simple pointing to the same object?

Upvotes: 10

Views: 7699

Answers (3)

timlyo
timlyo

Reputation: 2384

The assignment operator (=) only creates a reference to an object, and will create a new variable referencing the same memory address.

Copy will create a new object in memory, and then assign the variable to that.

For example:

import copy

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

node2.append(5)

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

prints out:

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

Upvotes: 16

xiº
xiº

Reputation: 4687

All python variables are bindings to some objects in memory.

  1. Does this code do anything?

Yes, it does. Actually it creates a new object in memory with new name.

  1. How does copy.copy(node) differ from node = node?

By assignment you are getting different names for the same object. So if you are really need a copy you should use shallow or deep copy.

Example:

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

So x and y have same id, while z has different.

Same here:

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

Quote from docs about shallow and deep copy:

The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):

A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

Upvotes: 10

Sergius
Sergius

Reputation: 986

At first, there are two types of object in Python: mutable and immutable. So, for example, you have list (lists are mutable):

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

But, if you use simple copy - changing b in this way will not affect a:

>>> import copy
>>> b = copy.copy(a)
>>> a
[3, 2]
>>> b
[3, 2]
>>> b[0] = 4
>>> b
[4, 2]
>>> a
[3, 2]

And one more thing: if a consists of other mutable objects, you have to use copy.deepcopy() to have full copy of that object, changing which will not affect a

Upvotes: 4

Related Questions