Python namespace

September 9, 2015

最近看 Intermediate Python , 看到关于 global、nonlocal 这两个关键字的 tip 时候,才想起自己虽然使用 Python 多年,但对于 变量的命名空间 其实还是有些模糊的。

在 Python 里,一个变量名是否已定义 是通过 LEGB 规则来查找的。所谓 LEGB 指的是 Local -> Enclosing function local -> Global (module) -> Built-in (Python)。如果按顺序查找四个 namespace ,仍没有找到对应变量名,则抛出 NameError 的异常。

如下几点是当初自己比较困惑,或者说是 Python 独特的地方:

  • 不属于 local namespace 、但属于其他命名空间里的变量可以访问,但无法重新绑定。如果进行赋值操作的话,是创建新的本地变量,而不是对原变量进行修改。如果想修改原变量的话,就要用到 global、nonlocal 这些关键字了。
  • if 语句、for 循环 并没有创建新的命名空间;这些语句里创建的新变量,在语句之后还是可以使用的。这一点对于从其他语言过来的程序员来说,有点出乎意料。
  • class 的属性,在 method 里是没法直接访问的。Python的面向对象实现,对于有 Java基础的学习者来说,总感觉有点怪怪的。

参考:

  1. Short Description of Python Scoping Rules
  2. Python Namespace and Scope
  3. Naming and binding
comments powered by Disqus