3

I have the following code:

class Hello(object):
    def __init__(self, names):
        self.names = names
    def getnames(self):
        return self.names  

if __name__ == "__main__":
    names = ['first', 'middle', 'last']     
    ob = Hello(names)
    a = ob.getnames()
    print a
    a.remove('first')
    print a
    print ob.getnames()

The following is the output:

['first', 'middle', 'last']
['middle', 'last']
['middle', 'last']

Is it because the method getnames is mutable? Or may be there is something else going on here. Can anyone explain? How do I make the method return the original list?

3 Answers 3

3

In Python, assignment never makes a copy of a data structure. It only makes a name refer to a value. Also, function invocation essentially assigns the actual arguments to the argument names. So nothing is copied in your code. The names a and ob.names refer to the same list. If you want to have two copies of the list (the original and one to modify), then you need to make a copy at some point. You'll have to decide where that makes the most sense.

You can copy a list a few different ways: list(L) or L[:] are the most common ways.

Sign up to request clarification or add additional context in comments.

Comments

3

have getnames return a copy:

def getnames(self):
    return self.names[:]

3 Comments

IMHO, this is too late. The original list with which the object was created might be modified outside this class, which would also change self.names, which is just a reference to the original list. Better to assign self.names = names[:] in __init__. Then the copy is made once, as the object is created, and there is no chance for Bad Things (i.e. external modifications) to occur during the object's lifespan.
Yes, that is true but you'd also want to have the method give out a copy too. As if you didn't you'd get the problem which the OP experienced. And that is what I wrote the answer to fix.
Fair point. It should be copied in both places, to guard against both kinds of inadvertent modification.
0

The name a refers to the same array that's stored in ob.names. If you change a, you change ob.names, because they both refer to the same thing.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.