Why are functions atomic?

Michael michael.forbes at gmail.com
Fri May 4 16:14:42 EDT 2007


On May 4, 4:13 am, Dustan <DustanGro... at gmail.com> wrote:
> On May 4, 1:36 am, Michael <michael.for... at gmail.com> wrote:
> > ...     def g(x=x):
> > ...         x = x + 1
> > ...         return x
> > ...     return g
> > >>> g = f(3)
> > >>> g()>
> > 4
> >>> g()
> 4
> >>> g()
> 4
> >>> g() # what is going on here????
> 4

Okay, so it is a bad design, but it illustrates the point.  What is
happening is that in the body of the function f, a new function is
defined using the value of x passed as an argument to f.  Thus, after
the call g = f(3), the body of f is equivalent to

def g(x=3):
    x = x + 1
    return x

This function is returned, so the call g() uses the default argument
x=3, then computes x = x+1 = 3+1 = 4 and returns 4.  Every call is
equivalent to g() == g(3) = 4.   Inside g, x is a local variable: it
does not maintain state between function calls.  (You might think that
the first example would allow you to mutate the x in the closure, but
this is dangerous and exactly what python is trying to prevent by
making x a local variable when you make assignments in g.  This is why
the interpreter complains.)

If you actually want to maintain state, you have to use a mutable
object like a list.  The following would do what you seem to expect.

>>> def f(x0):
...     def g(x=[x0]):
...         x[0] = x[0] + 1
...         return x[0]
...     return g
...
>>> g = f(3)
>>> g()
4
>>> g()
5
>>> h = f(0)
>>> h()
1
>>> h()
2
>>> g()
6




More information about the Python-list mailing list