Python 词法作用域规范 | Google 官方闭包写法
2025-07-23 12:00 更新
词法作用域(Lexical Scoping, 又名静态作用域)
Tip
可以使用。
定义:
嵌套的 Python 函数可以引用外层函数中定义的变量,但是不能对这些变量赋值。变量的绑定分析基于词法作用域,也就是基于静态的程序文本。任何在代码块内给标识符赋值的操作,都会让 Python 将该标识符的所有引用变成局部变量,即使读取语句写在赋值语句之前。如果有全局声明,该标识符会被视为全局变量。
一个使用这个特性的例子:
def get_adder(summand1: float) -> Callable[[float], float]:
"""返回一个函数,该函数会给一个数字加上指定的值."""
def adder(summand2: float) -> float:
return summand1 + summand2
return adder
(译者注:这个函数的用法大概是: fn = get_adder(1.2); sum = fn(3.4)
,结果是 sum == 4.6
。)
优点:
通常会产生更清晰、更优雅的代码。尤其是让熟练使用 Lisp 和 Scheme(还有Haskell, ML等)的程序员感到舒适。
缺点:
可能引发让人困惑的 bug,例如下面这个依据 PEP-0227 改编的例子:
i = 4
def foo(x: Iterable[int]):
def bar():
print(i, end='')
# ...
# 很多其他代码
# ...
for i in x: # 啊哈, i 是 Foo 的局部变量, 所以 bar 得到的是这个变量
print(i, end='')
bar()
因此 foo([1, 2, 3])
会输出 1 2 3 3
,而非 1 2 3 4
。
(译者注:x
是一个列表,for
循环其实是将x
中的值依次赋给i
。这样对i
的赋值就隐式的发生了,整个foo
函数体中的i
都会被当做局部变量,包括bar()
中的那个。这一点与 C++ 之类的语言还是有很大差别的。)
结论:
可以使用。
以上内容是否对您有帮助:
更多建议: