2010-02-19 3 views
4

Я пытаюсь раздобыть голову вокруг лямбда-выражений, замыканий и облаков на Python. Почему программа не разбивается на первую строчку здесь?Python Lambda поведение

>>> 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 
>>> 

ответ

6

Потому что это просто не то, как работают функции Python; это не является особенным для лямбда:

>>> 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 

Переменные обрабатываются при использовании, а не когда определена функция. Они даже просматриваются каждый раз, когда вызывается функция, которую вы обязательно найдете неожиданным, если вы используете фон C (например), но это не проблема в Python.

2

Ваше выражение лямбда не оценивается, пока вы его не назовете.

Он разобрался, поэтому синтаксическая ошибка вызовет трассировку.

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

Тела lambdas (и функции, определенные с def) в Python не оцениваются до их вызова. Имена всегда проверяются во время выполнения.

0

В первой строке вы создаете выражение, которое отличается от его оценки. Когда вы пытаетесь его оценить, тогда он не может найти символ a.

2

Переменные в Python могут использоваться до их установки. Это создаст ошибку времени выполнения, а не синтаксическую ошибку. Вот пример использования локальных переменных:

>>> 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 

Это в отличие от языков, которые считают Разыменование незадействованные или неопределенной переменной синтаксическую ошибку. Python не «захватывает» текущее состояние лексической области, он просто использует ссылки на изменяемые лексические области. Вот демонстрация:

>>> 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