2010-02-19 70 views
4

我試圖讓我的頭在Python中的lambda表達式,閉包和範圍。爲什麼程序不會在這裏的第一行崩潰?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功能的工作方式;這對lambda表達式並不特別:

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

您的lambda表達式在您調用它之前不會被評估。

它得到解析,這就是爲什麼語法錯誤會導致追溯。

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

在Python中調用lambda函數(和def定義的函數)的主體不會被評估。名稱始終在運行時查看。

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