constructor list slice confusion

Peter Otten __peter__ at web.de
Thu Jul 14 02:38:36 EDT 2005


Simon Morgan wrote:

> Can somebody please explain to me why:
> 
> class SomeClass:
>     def __init__(self, contents=[]):
>         self.contents = contents[:]
>     def add(self, element):
>         self.contents.append(element)
> 
> when called a second time (i.e. to create a new instance of a SomeClass
> object) results in self.contents being assigned an empty list when say for
> example I've done:
> 
> foo = SomeClass()
> foo.add(1)
> foo.add(2)
> 
> beforehand?
 
Maybe, after a little renaming you can see it yourself:

class SomeClass:
    def __init__(self, default_contents=[]):
        # make a copy of default_contents that is 
        # kept in a SomeClass instance
        self.contents = default_contents[:]
    def add(self, element):
        # modify the *copy* of default_contents...
        self.contents.append(element)

When you want modifiable defaults, you can use a class attribute:

>>> class SomeClass:
...     default_contents = []
...     def __init__(self, contents=default_contents):
...             self.contents = contents[:]
...     def add(self, elem): self.contents.append(elem)
...     def addDefault(self, elem): self.default_contents.append(elem)
...     def __repr__(self):
...             return "SomeClass(contents=%s, default_contents=%s)" % (
...             self.contents, self.default_contents)
...
>>> foo = SomeClass()
>>> foo
SomeClass(contents=[], default_contents=[])
>>> foo.add(1)
>>> foo.addDefault("x")
>>> foo
SomeClass(contents=[1], default_contents=['x'])
>>>
>>> bar = SomeClass()
>>> bar
SomeClass(contents=['x'], default_contents=['x'])
>>> bar.add(2)
>>> bar
SomeClass(contents=['x', 2], default_contents=['x'])

Peter



More information about the Python-list mailing list