On Nov 21, 6:31 am, J Kenneth King <[EMAIL PROTECTED]> wrote: > I recently encountered some interesting behaviour that looks like a bug > to me, but I can't find the appropriate reference to any specifications > to clarify whether it is a bug. > > Here's the example code to demonstrate the issue: > > class SomeObject(object): > > def __init__(self): > self.words = ['one', 'two', 'three', 'four', 'five'] > > def main(self): > recursive_func(self.words) > print self.words > > def recursive_func(words): > if len(words) > 0: > word = words.pop() > print "Popped: %s" % word > recursive_func(words) > else: > print "Done" > > if __name__ == '__main__': > weird_obj = SomeObject() > weird_obj.main() > > The output is: > > Popped: five > Popped: four > Popped: three > Popped: two > Popped: one > Done > [] > > Of course I expected that recursive_func() would receive a copy of > weird_obj.words but it appears to happily modify the object. > > Of course a work around is to explicitly create a copy of the object > property befor passing it to recursive_func, but if it's used more than > once inside various parts of the class that could get messy. > > Any thoughts? Am I crazy and this is supposed to be the way python works?
You are passing a mutable object. So it can be changed. If you want a copy, use slice: >>> L = [1, 2, 3, 4, 5] >>> copy = L[:] >>> L.pop() 5 >>> L [1, 2, 3, 4] >>> copy [1, 2, 3, 4, 5] ...in your code... def main(self): recursive_func(self.words[:]) print self.words ...or... >>> def recursive_func(words): >>> words = words[:] >>> if len(words) > 0: >>> word = words.pop() >>> print "Popped: %s" % word >>> recursive_func(words) >>> else: >>> print "Done" >>> >>> words = ["one", "two", "three"] >>> recursive_func(words) Popped: three Popped: two Popped: one Done >>> words ['one', 'two', 'three'] Though I haven't been doing this long enough to know if that last example has any drawbacks. If we knew more about what you are trying to do, perhaps an alternative would be even better. - Rafe -- http://mail.python.org/mailman/listinfo/python-list