A gotcha: Python pain point?
Terry Reedy
tjreedy at udel.edu
Tue Jun 12 03:53:01 EDT 2007
"Beorn" <bjorns at gmail.com> wrote in message
news:1181604836.292323.154510 at z28g2000prd.googlegroups.com...
| Consider this example:
|
| >>> def funcs(x):
| ... for i in range(5):
| ... def g(): return x + i
| ... yield g
|
| I would expect the value of x used in g to be that at the function
| declaration time, as if you've pass g a (x=x) argument,
Since x is constant during the funcs call, does not matter. Perhaps you
meant i, which does vary? If so, put i=i in the header -- or perhaps ii=i
to give two different names to two things which are made to have the same
value.
In any case, the simple rule is that default argument expressions in the
*header* are evaluated at definition time while the *body* (past the doc
string, if any) is executed after a call.
Some people expect defaults to be executed every call; others expect part
of the body to be executed once. Both get in trouble. For nested
functions, outer call time is inner definition time and this can confuses.
Defining (but delaying the call of) multiple identical inner functions, as
you do in the first example below, also confuses.
| especially
| after reading this post: http://lua-users.org/wiki/LuaScopingDiscussion
Lua is not Python.
| But:
|
| >>> [ fun() for fun in list(funcs(1)) ]
| [5, 5, 5, 5, 5]
|
| Whereas:
|
| >>> [ fun() for fun in funcs(1) ]
| [1, 2, 3, 4, 5]
As Calderone explained, the simple rule works as long as one keeps track of
what is called when.
Terry Jan Reedy
More information about the Python-list
mailing list