Python __import__ 函数中的 `globals` 和 `locals` 参数是什么?

11 投票
3 回答
5656 浏览
提问于 2025-04-16 11:05

在Python文档中,有一部分关于__import__的内容,我不太明白:

__import__(name[, globals[, locals[, fromlist[, level]]]])

这个函数的作用是导入名为name的模块。它可能会使用给定的globalslocals来决定如何在包的上下文中理解这个name。不过,标准的实现其实根本不使用locals这个参数,而只用globals来确定导入语句的包上下文。

关于模块名有什么需要“理解”的呢?什么是包的上下文?

使用这些参数的一个示例调用看起来是这样的:

spam = __import__('spam', globals(), locals(), [], -1)

为什么这个例子要把globals()locals()传给这个函数?如果我只提供globals()会怎样?或者都不提供呢?

我可能对导入模块时的命名空间逻辑有些不太明白。你能给我推荐一篇文章,解释一下这个内容,或者有关于__import__函数的例子吗?

3 个回答

-2

模块名称有什么好“解释”的?什么是包的上下文?

当你输入

>>> a

Python需要“解释”这个名称。它是全局的吗?还是局部的?

>>> def f(x):
...    return x * a

现在,x显然是局部的。a就得“解释”一下。是全局的?还是局部的?

为什么这个例子要把globals()和locals()传给函数?如果我只提供globals(),或者什么都不提供,会发生什么?

试试看吧。真的,动手玩一下比问别人要简单多了。

重要的是,你在>>>提示符下做的事情都是全局的。

你需要定义一些函数来创建一个局部的环境,这样你才能看到全局和局部之间的区别。

3

globals 是用来判断当前导入操作发生在哪个上下文中的。举个例子:

"""
/myproject/a/b.py
/myproject/a/foo.py
/myproject/c/d.py
/myproject/c/foo.py
"""

# Which foo gets imported?

import foo #1
foo = __import__('foo') #2

它们并不相同,因为在第二种情况下,没有简单的方法可以知道导入是从哪个模块发起的。__import__ 函数需要知道当前模块,以便正确导入 foo

__import__() 的内部,globals 被用来获取调用导入的当前模块的引用。根据 __import__源代码

返回正在执行导入操作的包。如果 globals 来自模块 foo.bar.bat(它本身不是一个包),那么这将返回 foo.bar 在 sys.modules 中的条目。如果 globals 来自一个包的 init.py,那么将返回该包在 sys.modules 中的条目,作为一个借用的引用。

6

标准的实现根本不使用它的 locals 参数,而只用 globals 来确定 import 语句的包上下文。

(来自 docs.python.org)

我还是不明白 globals 是怎么用的;有什么全局变量能影响 import 语句的工作方式呢?

编辑:在查看了 Python 2.5 源代码中的 import.c 后,我发现 __import__ 期望在 globals 中找到 __name____path__,以便根据这些变量中找到的路径来增强导入搜索路径,顺序是这样的。

撰写回答