Default Value

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Jun 19 21:17:54 EDT 2013


On Wed, 19 Jun 2013 12:17:35 -0700, Ahmed Abdulshafy wrote:

> I'm reading the Python.org tutorial right now, and I found this part
> rather strange and incomprehensible to me>
> 
> Important warning: The default value is evaluated only once. This makes
> a difference when the default is a mutable object such as a list,
> dictionary, or instances of most classes 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]
> 
> How the list is retained between successive calls? And why?

"How" is easy: it is stored inside the function object, where the code 
can get to it. To be precise, in the function object's __defaults__ 
attribute:

py> def f(a=1, b=5, c="hello world"):
...     pass
...
py> f.__defaults__
(1, 5, 'hello world')


"Why" is even easier: because the creator of Python decided to do it this 
way.

This is called "early binding" -- the default value is bound (assigned) 
to the parameter early in the process, when the function is created. This 
has a few advantages:

- It is the most efficient: the cost of evaluating the defaults 
  only happens once, when the function is created, not over and 
  over again, every time the function is called.

- It is usually what people expect. If you have a function with
  a default, you normally expect the default to be set once, and 
  not re-evaluated each time.

- If you start with "early binding", it is trivial to get "late
  binding" semantics instead; but if you start with late binding,
  it's less convenient to get early binding semantics.

The usual way to get the effect of late binding in Python is with a 
sentinel value to trigger the re-evaluation of the default. Normally, we 
would use None and a call-time check:

def function(arg, value=None):
    if value is None:
        # Re-calculate the default.
        value = ...
    # rest of code



-- 
Steven



More information about the Python-list mailing list