Поведение Python Lambda - PullRequest
       20

Поведение Python Lambda

5 голосов
/ 19 февраля 2010

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

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

Ответы [ 5 ]

6 голосов
/ 19 февраля 2010

Потому что это не совсем так, как работают функции 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 голосов
/ 19 февраля 2010

Переменные в 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
2 голосов
/ 19 февраля 2010

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

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

>>> foo = lambda x : x + a
>>> bar = lambda y : print y
SyntaxError: invalid syntax
0 голосов
/ 19 февраля 2010

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

0 голосов
/ 19 февраля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...