1

My question is regarding the rules of enclosing scope. In the snippet below if x=x is not passed to the header of F2 there will be an error

def f1():
    x = 88
    def f2(x=x): # Remember enclosing scope X with defaults
        print(x)
    f2()
f1()

however I dont understand why "x=x" is not needed in the lambda in the below snippet

def func():
   x = 4
   action = (lambda n: x ** n) # x remembered from enclosing def
   return action

x = func()
print(x(2))

1 Answers1

2

In the snippet below if x=x is not passed to the header of F2 there will be an error

No there won't:

>>> def f1():
...     x = 88
...     def f2():
...         print(x)
...     f2()
... 
>>> f1()
88

You only need the default parameter value hack when you're trying to pass a value that might get changed later. f2 as I've written it captures the variable x from the enclosing scope, so it will print whatever x happens to be at the time. As you've written it, it captures the current value of the variable x, not the variable itself.

For example:

>>> def f1():
...     x = 88
...     def f2():
...         print(x)
...     x = 44
...     f2()
... 
>>> f1()
44

>>> def f1():
...     x = 88
...     def f2(x=x):
...         print(x)
...     x = 44
...     f2()
... 
>>> f1()
88

For a very common real-life example of where this difference is important, see Why do lambdas defined in a loop with different values all return the same result? in the official FAQ.

abarnert
  • 354,177
  • 51
  • 601
  • 671