领域
您可以将“范围”视为您可以从代码中的特定点访问的名称集.
x = 1
y = 2
def foo():
z = 3 + y
# Here, I have access to `x, y, foo` -- They are in the current scope
# `z` is not in the current scope. It is in the scope of `foo`.
a = x + y
b = x + z # NameError because `z` is not in my scope.
请注意,在函数foo中,我可以访问“封闭”范围.我可以读取函数内定义的任何名称,也可以读取在创建函数的环境中定义的任何名称.
在示例中,在foo函数内部,范围包含x,y,foo,z和a(如果要定义b并且不抛出NameError,则它将包含b).
______________________________
| |
| Names in enclosing scope |
| {x, y, foo, ...} |
| |
| -------------------- |
| | function scope | |
| | {z} | |
| | (Also has access | |
| | enclosing scope) | |
| -------------------- |
| |
------------------------------
命名空间
命名空间是一个相关的概念.它通常被认为是一个拥有一组名称的对象.然后,您可以通过查看对象的成员来访问名称(以及它们引用的数据).
foo.x = 1
foo.y = 2
foo.z = 3
这里,foo是一个命名空间.我想你可以把命名空间看作一个名字的容器. python中最自然的命名空间单元是一个模块,虽然类,类的实例,函数可以是命名空间,因为在大多数情况下你可以将任意名称/数据附加到它们.
请注意,在python中,这些概念变得有点混乱,因为您可以将模块的作用域作为命名空间导入
# foo.py
x = 1
y = 1
# bar.py
import foo
print foo.x
print foo.y
请注意,foo的“全局”范围作为此示例中的命名空间foo导入到bar的全局范围中.
如果我们想要的话,我们也可以将foo的全局范围导入到没有命名空间的bar的全局范围内(尽管通常不鼓励这种做法):
# bar.py
from foo import *
print x
print y