[Python-Dev] nested scopes confusion
Jeremy Hylton
jeremy@zope.com
Tue, 4 Dec 2001 14:57:23 -0500 (EST)
> def functions():
> result = []
> for i in range(10):
> def mth(*args): return i
> result.append(mth)
> i = 25
> return result
>
> for mth in functions():
> print mth()
>>>>> "TH" == Thomas Heller <thomas.heller@ion-tof.com> writes:
TH> Reading PEP227, I can (barely) understand why it behaves this
TH> way.
It behaves this way because the reference to i in mth() uses the
binding for i introduced in functions(). The important point here is
that the binding is used, but i can be bound to different values at
different times. The function mth() sees the value that i is bound to
when it is called. In your example, mth() isn't called until after
the loop finishes executing.
TH> How do I achieve the desired effect? Note that the default
TH> argument trick (def mth(i=i): ...) does not work because *args
TH> is present.
All sorts of ways, I imagine. You could use a class:
class MthClass:
def __init__(self, val):
self.val = val
def mth(self, *args):
return self.val
This version is probably immediately obvious to the reader.
You could add an extra layer of functions, but this looks like a
pretty obscure use of nested scopes to me.
>>> def functions():
... result = []
... for i in range(10):
... def wrap(i):
... def mth(*args):
... return i
... return mth
... result.append(wrap(i))
... i = 25
... return result
...
>>> l = functions()
>>> l[0]()
0
>>> l[1]()
1
Jeremy