python中的作用域和命名空间之间的区别?

时间:2015-05-05 05:49:24

标签: python

我是python中的新手,请用示例描述Scopes和Namespaces之间的区别。

提前致谢

1 个答案:

答案 0 :(得分:10)

作用域

你可以想到"范围"作为您可以从代码中的特定点访问的名称集。

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的函数内,范围包含xyfooza (如果要定义b并且不抛出b,它将包含NameError

 ______________________________
 |                            |
 |   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中最自然的命名空间单位是module,但是class,类的实例,函数可以是命名空间,因为你可以将任意名称/数据附加到它们在大多数情况下。

请注意,在python中,这些概念变得有点混乱,因为您可以将模块的范围导入为命名空间

# foo.py
x = 1
y = 1

# bar.py
import foo
print foo.x
print foo.y

请注意"全球"在此示例中,foo的范围作为命名空间bar导入foo的全局范围。

如果我们愿意,我们也可以将foo的全局范围导入bar的全局范围而不使用命名空间(尽管通常不鼓励这种做法):

# bar.py
from foo import *
print x
print y