2010-02-19 23 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