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))
-
possible duplicate of Short Description of Python Scoping RulesMartin Tournoij– Martin Tournoij2014年08月14日 19:03:50 +00:00Commented Aug 14, 2014 at 19:03
-
I don't think that's a dup (although it's certainly related). Neither the question nor the accepted answer addresses the default parameter value hack at all.abarnert– abarnert2014年08月14日 19:08:19 +00:00Commented Aug 14, 2014 at 19:08
-
Are you sure this is the code you meant to post?Padraic Cunningham– Padraic Cunningham2014年08月14日 19:08:56 +00:00Commented Aug 14, 2014 at 19:08
1 Answer 1
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.