0

I'm trying to append items to a list in an instantiated object:

class Room(object):
    def __init__(self, name, contents=[]):
        self.name = name
        self.contents = contents


living_room = Room('living room')
dining_room = Room('dining room')

print(living_room.contents)  # []
print(dining_room.contents)  # []

living_room.contents.append('lamp')

print(living_room.contents)  # ['lamp']
print(dining_room.contents)  # ['lamp']

The behavior I would expect would be for the lamp to be in living_room.contents, but not in dining_room.contents. Can anyone explain this?

T. Arboreus
  • 1,067
  • 1
  • 9
  • 17

1 Answers1

2

contents is a mutable default argument. It's default value (the empty list) is only created once, not for every call.

Here are more details: http://docs.python-guide.org/en/latest/writing/gotchas/

jab
  • 56
  • 1
  • That's true, but I'm not sure that it addresses the question entirely. I didn't call the instantiated object again, I appended something to it and it also appended to another instantiated object of the same class. Is it really true that you can't add things to a list in an instantiated object? – T. Arboreus May 07 '16 at 21:09
  • As far as I know, the default argument is created in the scope of the function which in turn is created in the scope of the class. So all instances of `Room` share the list. You can hand each instance its own list if you want them to be independent: `Room('living room', contents=[])` – jab May 07 '16 at 21:17
  • OK, thank you. What I wound up doing was just putting self.contents = [] in the body of the __init__ method and leaving contents out of the arguments. – T. Arboreus May 07 '16 at 21:25
  • If you plan on instantiating Room and occasionally passing contents then you could easily do the following! Use a check to determine the value of contents (if contents == []: self.__contents = [] else: self.__contents = contents) This allows you the flexibility you originally desired, however I would recommend removing the default parameter! – TheLazyScripter May 07 '16 at 21:28