6

I have been playing with the deepcopy function and the copy function and I get the same issue with both of them. It is like the copy was a reference (or a pointer) instead of a proper copy. I am working with data records (classes) in Python, maybe it could be that.. I show you an example:

>>> import copy >>> class player1: ... age = 23 ... score = 1 >>> class player2: ... age = 14 ... score = 2 >>> player3 = copy.deepcopy(player1) 

I print the parameters.

>>> print player1.age, player1.score 23 1 >>> print player2.age, player2.score 14 2 >>> print player3.age, player3.score 23 1 

Now I increment the score parameter in player1 data record.

>>> player1.score += 3 

And I print the results again.

>>> print player1.age, player1.score 23 4 >>> print player2.age, player2.score 14 2 >>> print player3.age, player3.score 23 4 

WHY HAS PLAYER 3 CHANGED? I just incremented a parameter in player1, not player3. It is mutable instead of immutable.

Thanks in advance.

0

3 Answers 3

11

The problem is that you are actually copying the class definition and not an instance of the class.

Another problem of the code is that the attributes age and score are part of the class and will be shared between all instances of that class. This is probably not what you intended.

What you probably want to do is:

import copy class Player: def __init__(self, age, score): self.age = age self.score = score player1 = Player(23, 1) player2 = Player(14, 2) player3 = copy.deepcopy(player1) player1.age += 1 print "player1.age", player1.age print "player3.age", player3.age 

This gives you what you expect:

player1.age 24 player3.age 23 
Sign up to request clarification or add additional context in comments.

2 Comments

I disagree that the fact that age and score were class attributes is responsible for the observed behaviour; if player3 were really a different class, the OP wouldn't have had this problem. I agree they should be instance attributes, but that's something different.
@DSM: Yes, agreed. I got obsessed with this at first, not even seeing that there were no class instances at all. I corrected this.
3

This is working as designed.

In your sample code, you are copying class definitions, not object instances. From copy module manual page:

It does “copy” functions and classes (shallow and deeply), by returning the original object unchanged 

Hence:

player3 = copy.deepcopy(player1) 

is the same as:

player3 = player1 

However, if you copied instances of the classes, you would get the expected result:

player3 = copy.deepcopy(player1()) 

Comments

2

From the documentation (emphasis mine):

This version does not copy types like module, class, function, method, nor stack trace, stack frame, nor file, socket, window, nor array, nor any similar types.

You're trying to copy classes, and so:

>>> player3 = copy.deepcopy(player1) >>> player1 is player3 True 

but

>>> p1 = player1() >>> p2 = player2() >>> p3 = copy.deepcopy(p1) >>> p1 is p3 False 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.