Python __import__ 函数中的 `globals` 和 `locals` 参数是什么?
在Python文档中,有一部分关于__import__
的内容,我不太明白:
__import__(name[, globals[, locals[, fromlist[, level]]]])
这个函数的作用是导入名为
name
的模块。它可能会使用给定的globals
和locals
来决定如何在包的上下文中理解这个name
。不过,标准的实现其实根本不使用locals
这个参数,而只用globals
来确定导入语句的包上下文。
关于模块名有什么需要“理解”的呢?什么是包的上下文?
使用这些参数的一个示例调用看起来是这样的:
spam = __import__('spam', globals(), locals(), [], -1)
为什么这个例子要把globals()
和locals()
传给这个函数?如果我只提供globals()
会怎样?或者都不提供呢?
我可能对导入模块时的命名空间逻辑有些不太明白。你能给我推荐一篇文章,解释一下这个内容,或者有关于__import__
函数的例子吗?
3 个回答
模块名称有什么好“解释”的?什么是包的上下文?
当你输入
>>> a
Python需要“解释”这个名称。它是全局的吗?还是局部的?
>>> def f(x):
... return x * a
现在,x
显然是局部的。a
就得“解释”一下。是全局的?还是局部的?
为什么这个例子要把globals()和locals()传给函数?如果我只提供globals(),或者什么都不提供,会发生什么?
试试看吧。真的,动手玩一下比问别人要简单多了。
重要的是,你在>>>
提示符下做的事情都是全局的。
你需要定义一些函数来创建一个局部的环境,这样你才能看到全局和局部之间的区别。
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 中的条目,作为一个借用的引用。
标准的实现根本不使用它的
locals
参数,而只用globals
来确定import
语句的包上下文。
(来自 docs.python.org)
我还是不明白 globals
是怎么用的;有什么全局变量能影响 import
语句的工作方式呢?
编辑:在查看了 Python 2.5 源代码中的 import.c
后,我发现 __import__
期望在 globals
中找到 __name__
或 __path__
,以便根据这些变量中找到的路径来增强导入搜索路径,顺序是这样的。