Non-intuitive treatment of empty list as default parameter value on class method

Hans Peter de Koning hpdk at chello.nl
Mon Mar 24 12:21:47 CET 2003


If on a class method you define a default parameter value equal to an empty
list, and then start to create instances of the class using constructor
calls with default values (i.e. no parameter value given), you get the
following IMHO non-intuitive behaviour (Python 2.2 /  IDLE was used):

>>> class C:
 def __init__(self, aList=[]):
  self.someList = aList

>>> c1=C()   # create an instance of C with default parameters
>>> print c1.someList
[]
>>> c1.someList.append('spam')
>>> print c1.someList
['spam']
>>> c2=C()
>>> print c2.someList
['spam']
>>> print id(c1.someList), id(c2.someList)     # someList in c1 and c2 point
to the same list object
13244816 13244816

Apparently the empty list is created by reference in the class' namespace
and being mutable the reference persists after the c1.someList.append call
and the second (or subsequent) class instantiation call. A quick way to get
the intended behaviour is by explicit parameter assignment:

>>> c1=C(aList=[])
>>> print c1.someList
[]
>>> c1.someList.append('spam')
>>> print c1.someList
['spam']
>>> c2=C(aList=[])
>>> print c2.someList
[]
>>> print id(c1.someList), id(c2.someList)
13438160 13484848

I sense some inconsistency here because apparently in the global namespace
different empty list instances are created.

With an adapted class definition again the intended behaviour can be
achieved:

>>> class C:
 def __init__(self, aList=None):
  if aList is None:
   self.someList = []
  else:
   self.someList = aList

>>> c1 = C()
>>> c1.someList.append('spam')
>>> print c1.someList
['spam']
>>> c2 = C()
>>> print c2.someList
[]
>>> print id(c1.someList), id(c2.someList)
13656800 13681120

Is the behaviour as illustrated in the first excerpt as intended? Can
somebody enlighten me?

Best regards, HPdK






More information about the Python-list mailing list