5

I'm trying to get my head around lambda expressions, closures and scoping in Python. Why does the program not crash on the first line here?

>>> foo = lambda x: x + a
>>> foo(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
NameError: global name 'a' is not defined
>>> a = 5
>>> foo(2)
7
>>> 
0

5 Answers 5

6

Because that's just not how Python functions work; it's not special to lambdas:

>>> def foo(x):
...   return x + a
>>> foo
<function foo at 0xb7dde454>
>>> foo(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in foo
NameError: global name 'a' is not defined

Variables are looked up when used, not when a function is defined. They are even looked up each time the function is called, which you will definitely find unexpected if you're coming from a C background (for example), but this isn't a problem in Python.

Sign up to request clarification or add additional context in comments.

Comments

2

Your lambda expression doesn't get evaluated until you call it.

It does get parsed, which is why a syntax error would cause a traceback.

>>> foo = lambda x : x + a
>>> bar = lambda y : print y
SyntaxError: invalid syntax

Comments

2

Variables in Python may be used before they are set. This will generate a runtime error, not a syntax error. Here's an example using local variables:

>>> def f():
...     return a
...     a = 3
... 
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in f
UnboundLocalError: local variable 'a' referenced before assignment

This is in contrast to languages which consider dereferencing an unassigned or undefined variable a syntax error. Python doesn't "capture" the current state of lexical scope, it just uses references to mutable lexical scopes. Here's a demonstration:

>>> def f(): return a
... 
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in f
NameError: global name 'a' is not defined
>>> a = 3
>>> f()
3

Comments

0

The bodies of lambdas (and functions defined with def) in Python are not evaluated until they are called. Names are always looked up at runtime.

Comments

0

on the first line you create expression, which is different from evaluating it. When you try to evaluate it, this is then it cannot find symbol a .

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.