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++ 之类的语言还是有很大差别的。)

结论:

可以使用。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号