Aaron "Castironpi" Brady wrote:
On Sep 28, 2:52 am, Steven D'Aprano <[EMAIL PROTECTED]

As for why the complicated version works, it may be clearer if you expand
it from a one-liner:

# expand: f[ n ]= (lambda n: ( lambda: n ) )( n )

inner = lambda: n
outer = lambda n: inner
f[n] = outer(n)

outer(0) => inner with a local scope of n=0
outer(1) => inner with a local scope of n=1 etc.

For this to work, the 'expansion' has to be mental and not actual.
Which is to say, inner must be a text macro to be substituted back into outer.

Then, later, when you call inner() it grabs the local scope and returns
the number you expected.


I must have misunderstood.  Here's my run of your code:

I cannot speak to what Steven meant, but

inner = lambda: n

when inner is actually compiled outside of outer, it is no longer a closure over outer's 'n' and 'n' will be looked for in globals instead.

outer = lambda n: inner
outer(0)
<function <lambda> at 0x00A01170>
a=outer(0)
b=outer(1)
a()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
NameError: global name 'n' is not defined

Why doesn't 'inner' know it's been used in two different scopes, and
look up 'n' based on the one it's in?

That would be dynamic rather than lexical scoping.

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to