On 25 Oct 2005 15:57:41 -0700, "the.theorist" <[EMAIL PROTECTED]> wrote:
> >Bruno Desthuilliers wrote: >> the.theorist a =E9crit : >> > I have a small, simple class which contains a dictionary (and some >> > other stuff, not shown). I then have a container class (Big) that holds >> > some instances of the simple class. When I try to edit the elements of >> > the dictionary, all instances obtain those changes; I want each >> > instance to hold separate entries. >> > >> > #----------Begin module test.py >> > class ex: >> >> class ex(object): # oldstyle classes are deprecated >> >> > def __init__(self, val=3D{}): >> > self.value =3D val >> >> You didn't search very long. This is one of the most (in)famous Python >> gotchas: default args are evaluated *only once*, when the function >> definition is evaluated (at load time). This is also a dirty trick to >> have a 'static' (as in C) like variable. >> >> The solution is quite simple: >> class ex(object): >> def __init__(self, val=3DNone): >> if val is None: val =3D {} >> self.value =3D val >> >> (snip) > >Hey, that was extremely helpful. I suspect that the default args >evaluation is optimized for speed. So it makes sense to use the None >assignment, and a test condition later. That sounds like you missed the important point: The reason for using None instead of {} as a default argument is that default arguments are only evaluated when the function is defined, not when it's called, so if the default value is {}, that very _same_ dict will be used as default for the next call to __init__, so you will have every instance of ex looking at the same val and binding it to its self.value, and then if one instance modifies it (which it can, since a dict is mutable), the other instances will see the modification in their self.value dicts. The None default prevents re-use of a dict that wasn't actually passed in as an argument replacing the default in the call. The call-time test for None discovers that a fresh dict is needed, and self.value = {} creates that fresh dict when __init__ executes, so the new instance gets its own separate self.value dict. Nothing to do with optimization. In fact, re-using the shared default dict would be faster, though of course generally wrong. > >Worked like a charm, Thanks! > Just wanted to make sure you realize why it made a difference, in case ;-) Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list