class MyClass:
def __init__(self):
self.__data = []
self.doSomething()
def doSomething(self):
#[self.__buckets.append([1,2,i] ) for i in range (0,4)]
[self.__data.append(i ) for i in range (0,4)]
def getData(self):
return self.__data
def modBucket(self):
h = self.__data[2]
h = 5
def modBucket2(self):
h = self.__data
h[2] = 5
c = MyClass()
print "init:", c.getData()
c.modBucket()
print "mod1:", c.getData()
c.modBucket2()
print "mod2:", c.getData()
print "-------------------------"
The output of running this code is:init: [0, 1, 2, 3] mod1: [0, 1, 2, 3] mod2: [0, 1, 5, 3] ------------------------
Notice the problem, if you ask for the whole object, you get if by reference, if you ask for a part of it, you get a copy!!!!
Haven’t yet found the logic for this, any directions welcome.
December 28, 2007 at 3:50 pm
The culprit is not argument passing, but assignment.
The semantics of assignment in Python is quite unusual, but is perfectly clear when you get used to it: when you say a=b, you rebind the name a to the object b. This means that modBucket binds two different objects to the same local variable h and then exits, so it does nothing. modBucket2, on the other hand, actually modifies self.__data.
More info here: http://www.python.org/doc/faq/programming/#how-can-my-code-discover-the-name-of-an-object
Oh, and BTW: that list comprehension in doSomething is quite un-Pythonic: usually you are advised to only use functional-style clauses without side effects in list comprehensions and generator expressions.
January 10, 2010 at 3:35 am
[...] O problema neste caso não está na forma como o objeto está sendo passado. Na verdade, o que leva a esse comportamento é o método de atribuição do Python. [...]
October 29, 2011 at 8:10 pm
Effects of Steroids…
[...]python: copy by reference, copy by value, shit it depends on what you copy! « Look here first![...]…
November 27, 2011 at 2:16 pm
cheap trainers…
[...]python: copy by reference, copy by value, shit it depends on what you copy! « Look here first![...]…