Reputation: 7680
I have a piece of code that is supposed to use shallow copy to make automatically changing variables: pos_x and pos_y, when pos is changed.
import copy
class AClass:
def __init__(self):
self.pos = [1, 2]
self.pos_x = copy.copy(self.pos[0])
self.pos_y = copy.copy(self.pos[1])
temp = AClass()
temp.pos[0] = 5
print(temp.pos_x)
Why does that output 1 instead of 5?
Upvotes: 1
Views: 153
Reputation: 103
Because what your code is doing is not what you think it is doing. The shallow copy of a list will make a new list and add references to the objects inside it.
The thing is that the reference of the two elements (Which are numbers) you have there are references to an immutable object 1 and 2, and not to the specific 1 and 2 inside your list. You can check that by using id:
temp = AClass()
id(temp.pos[0])
id(1)
The IDs are the same, which means that your temp.pos[0] is pointing to the "global" 1.
If you really wanted to do something like what you thought without big changes (like using methods to change pos), it would have to be something like this:
import copy
class AClass:
def __init__(self):
self.pos = [[[1]], [[2]]]
self.pos_x = copy.copy(self.pos[0])
self.pos_y = copy.copy(self.pos[1])
Then, copy would create a new list, and insert the reference to the list with the 1 there. And changing t[0][0][0] would also change x[0][0]. But that's probably far from being a good way to do it. And again you can verify that the ids of t[0][0] and x[0] are the same, so they are both pointing to the same list.
Upvotes: 1
Reputation: 49813
The sequence of events was:
temp
, which involved assigning copies of elements of temp.pos
to temp.pos_x
and temp.pos_y
.temp.pos
.temp.pos_x
.There is nothing in those code that causes pos_x
or pos_y
to change when pos
changes.
Upvotes: 1