Why do class methods share mutable defaults between instances?
Ron Teeter
ron.teeter at supplysolution.com
Tue Apr 30 18:50:25 EDT 2002
Asked and answered... little more digging around and I found this...
Python documentation, section 4.7.1, excerpt:
"""
Important warning: The default value is evaluated only once. This makes a
difference
when the default is a mutable object such as a list or dictionary. For example,
the following function accumulates the arguments passed to it on subsequent
calls:
def f(a, L=[]):
L.append(a)
return L
print f(1)
print f(2)
print f(3)
This will print
[1]
[1, 2]
[1, 2, 3]
If you don't want the default to be shared between subsequent calls, you can
write
the function like this instead:
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
"""
Chalk it up to insufficient familiarity with default value initialization.
Thanks anyway,
Ron Teeter
> -----Original Message-----
> From: python-list-admin at python.org
> [mailto:python-list-admin at python.org]On Behalf Of Ron Teeter
> Sent: Tuesday, April 30, 2002 6:12 PM
> To: python-list at python.org
> Subject: Why do class methods share mutable defaults between
> instances?
>
>
> Greetings,
>
> Today I made a rather perplexing discovery. It appears that
> mutable defaults
> in class methods are shared between instances. Here is a
> simple example of
> the scenario.
>
> class Demo:
> def __init__(self,name,dict={},list=[]):
> self.name = name
> self.dict = dict
> self.list = list
> self.dict[name] = name
> self.list.append(name)
>
> def dump(name,dict={},list=[]):
> print name,dict,list
>
> for name in ['A1','B1','C1']:
> tmp = Demo(name)
> dump(tmp.name,tmp.dict,tmp.list)
>
> >>>
> A1 {'A1': 'A1'} ['A1']
> B1 {'B1': 'B1', 'A1': 'A1'} ['A1', 'B1']
> C1 {'C1': 'C1', 'B1': 'B1', 'A1': 'A1'} ['A1', 'B1', 'C1']
> >>>
>
> My intent was that each time Demo was instanciated a new
> dictionary would be
> assigned to 'dict' if there was no corresponding argument.
> However, the
> behavior is as though the {} were replaced with a class constant.
>
> In order to avoid this behavior I had to reorganize Demo as follows:
>
> class Demo2:
> def __init__(self,name,dict=None,list=None):
> if dict==None:
> dict = {}
> if list==None:
> list = []
> self.name = name
> self.dict = dict
> self.list = list
> self.dict[name] = name
> self.list.append(name)
>
> I am wondering if this is a bug or a subtle usage error on my
> part. I would
> expect that syntax on functions would be valid for class
> methods as well, but
> in this case you get drastically different behaviors.
>
> Thanks,
>
> Ron Teeter
>
>
>
More information about the Python-list
mailing list