[Tutor] Default list arguments in __init__

spir denis.spir at free.fr
Sat Feb 21 20:55:10 CET 2009


Le Sat, 21 Feb 2009 11:38:49 -0800,
Moos Heintzen <iwasroot at gmail.com> s'exprima ainsi:

> Hi,
> 
> This behavior was totally unexpected. I only caught it because it was 
> the only thing I changed.
> 
>  >>> class foo:
> ...     def __init__(self, lst=[]):
> ...             self.items = lst
> ...
>  >>> f1 = foo()
>  >>> f1.items
> []
>  >>> f1.items.append(1)
>  >>> f2 = foo()
>  >>> f2.items
> [1]
> 
> Huh? lst is a reference to the *same list* every instance?

Yop! Default args are evaluated once and only once at func def time. Very common trap, indeed! Note that this has nothing to do with __init__, nore with methods specifically. You can reproduce your example with a "free" function.

> I guess I have to do it like this. It seems to work. (i.e. every foo 
> instance with default lst now has a unique new list.)
> 
> def__init__(self, lst=None):
>     self.items = lst or []

This is the right remedy. Except that I would write
    self.items = [] if lst is None else lst
to avoid "tricking" with bools (personal taste).

denis
------
la vita e estrany


More information about the Tutor mailing list