Python中作用域和命名空间的区别是什么?

9

我是Python的新手,请用实例描述作用域和命名空间的区别。

感谢您提前的帮助。


我的第一反应与@Shashank相同。所以我通过谷歌搜索来看看前几个结果会出现什么。程序员问答网站和stackoverflow上有两个相关的问题位于前三个结果中。因此,虽然这是一个容易谷歌搜索到的问题,但我认为不应该给它任何“-1”。 - Scott
1个回答

14

作用域

"作用域"可以理解为你可以从代码中的特定点访问的名称集合。

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被定义并且不会引发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 中,命名空间最自然的单元是 module,尽管 classclass 的实例、function 可以在大多数情况下成为命名空间,因为你可以向它们附加任意的名称/数据。

请注意,在 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接