词法作用域(Lexical Scoping)

Tip

推荐使用

定义:

嵌套的Python函数可以引用外层函数中定义的变量, 但是不能够对它们赋值. 变量绑定的解析是使用词法作用域, 也就是基于静态的程序文本. 对一个块中的某个名称的任何赋值都会导致Python将对该名称的全部引用当做局部变量, 甚至是赋值前的处理. 如果碰到global声明, 该名称就会被视作全局变量.

一个使用这个特性的例子:




  1. def get_adder(summand1):
    """Returns a function that adds numbers to a given number."""
    def adder(summand2):
    return summand1 + summand2

    return adder




(译者注: 这个例子有点诡异, 你应该这样使用这个函数: sum = get_adder(summand1)(summand2) )
优点:
通常可以带来更加清晰, 优雅的代码. 尤其会让有经验的Lisp和Scheme(还有Haskell, ML等)程序员感到欣慰.
缺点:

可能导致让人迷惑的bug. 例如下面这个依据 PEP-0227 的例子:




  1. i = 4
    def foo(x):
    def bar():
    print i,
    # …
    # A bunch of code here
    # …
    for i in x: # Ah, i is local to Foo, so this is what Bar sees
    print i,
    bar()




因此 foo([1, 2, 3]) 会打印 1 2 3 3 , 不是 1 2 3 4 .

(译者注: x是一个列表, for循环其实是将x中的值依次赋给i.这样对i的赋值就隐式的发生了, 整个foo函数体中的i都会被当做局部变量, 包括bar()中的那个. 这一点与C++之类的静态语言还是有很大差别的.)
结论:
鼓励使用.