我正试图了解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
>>>
答案 0 :(得分:6)
因为这不是Python功能的工作原理;对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
使用时会查找变量,而不是在定义函数时查找变量。每次调用函数时都会查找它们,如果你来自C背景(例如),你肯定会发现意外,但这在Python中不是问题。
答案 1 :(得分:2)
在调用lambda表达式之前,不会对其进行评估。
它会被解析,这就是语法错误会导致回溯的原因。
>>> foo = lambda x : x + a
>>> bar = lambda y : print y
SyntaxError: invalid syntax
答案 2 :(得分: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
答案 3 :(得分:0)
Python中的lambdas体(以及用def定义的函数)在被调用之前不会被计算。名字总是在运行时查找。
答案 4 :(得分:0)
在您创建表达式的第一行上,这与评估它不同。当您尝试评估它时,它就找不到符号a。