TheLizzard
TheLizzard

Reputation: 7680

Python shallow copy doesn't automatically change the variable when the other variable is changed

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

Answers (2)

rasc42
rasc42

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

Scott Hunter
Scott Hunter

Reputation: 49813

The sequence of events was:

  1. Created temp, which involved assigning copies of elements of temp.pos to temp.pos_x and temp.pos_y.
  2. Replace the value of temp.pos.
  3. Print the value of temp.pos_x.

There is nothing in those code that causes pos_x or pos_y to change when pos changes.

Upvotes: 1

Related Questions