default value for __init__ doesn't work

人言落日是天涯,望极天涯不见家 kelvin.you at gmail.com
Sat Sep 11 08:05:04 CEST 2010


On Sep 11, 1:55 pm, 人言落日是天涯,望极天涯不见家 <kelvin.... at gmail.com> wrote:
> On Sep 11, 1:14 pm, Benjamin Kaplan <benjamin.kap... at case.edu> wrote:
>
>
>
> > On Sat, Sep 11, 2010 at 12:38 AM, 人言落日是天涯,望极天涯不见家 <kelvin.... at gmail.com> wrote:
> > > Please look at below code snippet:
> > > class test():
> > >    def __init__(self, a, dic={}):
> > >        self.a = a
> > >        self.dic = dic
> > >        print('__init__ params:',a, dic)
>
> > This is a pretty popular mistake to make. Default arguments aren't
> > evaluated when you call the method. They're created when the method is
> > created (meaning when you first run the file and the class itself is
> > defined), and that's it. Because you do self.dic = dic, this means
> > that every instance of the object will receive the same dict object.
> > Change it for one object, and the change will show up in all of them.
> > The solution to this is to use a sentinel value, like None
>
> > def __init__(self, a, dic=None) :
> >     if dic is None :
> >         self.dic = {}
> >     else :
> >         self.dic = dic
>
> > If None is a valid value for the parameter, make a sentinel object and use that
>
> > sentinel = object()
> > def __init__(self, a, dic=sentinel) :
> >     if dic is sentinel : #you want to use is here, not ==
> >       ...
>
> Got it. Thanks for point out my mistake. You are very nice.

I remember the same issue was occurred in my C++ program. There I have
a function with a parameter referenced a default object . May be C++
also constructs the the default arguments before the function is
called.
Thank you again to help me so much!



More information about the Python-list mailing list