Take the 2-minute tour ×

A simple question, perhaps, but I can't quite phrase my Google query to find the answer here. I've had the habit of making copies of objects when I pass them into object constructors, like so:

def __init__(self, name):
    self._name = name[:]

However, when I ran the following test code, it appears to not be necessary, that Python is making deep copies of the object values upon object instantiation:

>>> class Candy(object):
...     def __init__(self, flavor):
...             self.flavor = flavor
>>> flav = "cherry"
>>> a = Candy(flav)
>>> a
<__main__.Candy object at 0x00CA4670>
>>> a.flavor
>>> flav += ' and grape'
>>> flav
'cherry and grape'
>>> a.flavor

So, what's the real story here? Thanks!


Thanks to @Olivier for his great answer. The following code documents a better example that Python does copy by reference:

>>> flav = ['a','b']
>>> a = Candy(flav)
>>> a.flavor
['a', 'b']
>>> flav[1] = 'c'
>>> flav
['a', 'c']
>>> a.flavor
['a', 'c']
share|improve this question
add comment

2 Answers

up vote 12 down vote accepted

It is because strings are immutable.

The operator +=, rather confusingly, actually reassigns the variable it is applied to, if the object is immutable:

s = 'a'
ids = id(s)
s += 'b'
ids == id(s) # False, because s was reassigned to a new object

So, in your case, in the beginning, both flav and a.flavor point to the same string object:

flav --------\
a.flavor ----/

But when you write flav += 'and grape' the variable flav gets reassigned to a new string object:

flav --------> 'cherry and grape'
a.flavor ----> 'cherry' # <-- that string object never changes

It is confusing, because usually, when you call an operator on a variable, it doesn't change the variable. But just in the case of an immutable object, it does reassign the variable.

So the final answer to your question is, yes, it makes sense to copy the objects upon instantiation, especially if you are expecting a mutable object (which is often the case). It the object was immutable, it will not harm to copy it anyway.

share|improve this answer
To clarify, self.flavor = flavor does copy by reference, but because strings are immutable the referenced object can not be changed. Therefore, flav += ' and grape actually creates a new string object and makes flav reference it. –  taleinat Jun 4 '10 at 13:56
@taleinat: thanks, I updated the answer, hoping it doesn't get to confusing. –  Olivier Verdier Jun 4 '10 at 14:03
Thanks guys for your answers. I guess then, I'm still left wondering if copying objects upon instantiation is a good idea, since I don't see many places where it's done. Any suggestions there? –  daveslab Jun 4 '10 at 14:21
@daveslab: if you still have questions, why accept this answer? –  S.Lott Jun 4 '10 at 14:44
@S.Lott because it is out of the scope of the question I stated above, which was answered by @Olivier. The real criticism you could've brought is that I should've opened a new question about Python style, but I was hoping for just brief words of advice and didn't want to go through all the trouble. So be it. –  daveslab Jun 4 '10 at 16:23
show 1 more comment

it appears to not be necessary

Appears? Your question is entirely about design and meaning. This is not a preference or habit question.

Does the class contract include the ability modify a mutable argument? If so, do NOT make a copy.

Does the class contract assert that a mutable argument will not be modified? If so, you MUST make a copy.

Your questions is answered entirely by the contract definition for the class.

share|improve this answer
I see the area of your confusion. I should've had a sentence at the top saying that my goal was to ensure that the variables passed to __init__ were copied by value, not by reference into the object. What I meant by It appears to not be necessary is that it seemed that I didn't need to use my copying methods because Python was doing it anyway. I was incorrect. –  daveslab Jun 4 '10 at 16:20
@daveslab: Don't comment. Fix the question. Please update the question to clearly state what your objective actually is. Other people read these questions trying to learn Python and good program design. Please fix the question to be perfectly clear. –  S.Lott Jun 5 '10 at 1:21
add comment

Your Answer


