Search code examples
pythonmutablearguments

Python object initialization bug. Or am I misunderstanding how objects work?


  1 import sys
  2 
  3 class dummy(object):
  4     def __init__(self, val):
  5         self.val = val
  6 
  7 class myobj(object):
  8     def __init__(self, resources):
  9         self._resources = resources
 10 
 11 class ext(myobj):
 12     def __init__(self, resources=[]):
 13         #myobj.__init__(self, resources)
 14         self._resources = resources
 15 
 16 one = ext()
 17 one._resources.append(1)
 18 two = ext()
 19 
 20 print one._resources
 21 print two._resources
 22 
 23 sys.exit(0)

This will print the reference to the object assigned to one._resources for both one and two objects. I would think that two would be an empty array as it is clearly setting it as such if it's not defined when creating the object. Uncommenting myobj.__init__(self, resources) does the same thing. Using super(ext, self).__init__(resources) also does the same thing.

The only way I can get it to work is if I use the following:

two = ext(dummy(2))

I shouldn't have to manually set the default value when creating the object to make this work. Or maybe I do. Any thoughts?

I tried this using Python 2.5 and 2.6.


Solution

  • You should change

    def __init__(self, resources=[]):
        self._resources = resources
    

    to

    def __init__(self, resources=None):
        if resources is None:
            resources = []
        self._resources = resources
    

    and all will be better. This is a detail in the way default arguments are handled if they're mutable. There's some more information in the discussion section of this page.