Weird side effect of default parameter

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri May 4 08:26:24 EDT 2018


On Thu, 03 May 2018 19:47:37 +0000, Robert Latest via Python-list wrote:

> Hello,
> 
> I don't understand the behavior of the code below. Why does the dict
> property "a" of both objects contain the same keys? This is only if
> "a=dict" is in the initializer. If I put self.a = dict() into the init
> function, I get two separate dicts


Python function default values use *early binding*: the default parameter 
is evaluated, ONCE, when the function is defined, and that value is used 
each time it is needed.

The opposite is *late binding*: the default parameter is not evaluated 
until it is actually needed, and then re-evaluated each time it is needed.

Both approaches have their pros and cons, but early binding is better as 
the language supported feature, since it is easy to build late binding 
for yourself:

    def __init__(self, x, a=None):
        if a is None:
            a = dict()
        self.x = x
        self.a = a
        self.a[x] = x


whereas if the language used late binding, it would be really difficult 
to build early binding on top of it.

The interaction between early-binding defaults and mutable values like 
lists and dicts is a well-known "gotcha" (or at least, it is well-known 
to those of us who have come across it before). It is even a FAQ:

https://docs.python.org/dev/faq/programming.html#why-are-default-values-
shared-between-objects


See also: http://www.effbot.org/zone/default-values.htm



-- 
Steve




More information about the Python-list mailing list