实际上,的行为
__import__()完全是由于
import调用的执行
__import__()。基本上有五种不同的
__import__()调用方式
import(有两个主要类别):
import pkgimport pkg.modfrom pkg import mod, mod2from pkg.mod import func, func2from pkg.mod import submod
在第一种 和 第二种情况下,该
import语句应将“最左侧”模块对象分配给“最左侧”名称:
pkg。之后,
importpkg.mod您可以执行
pkg.mod.func()该操作,因为该
import语句引入了本地名称
pkg,这是具有
mod属性的模块对象。因此,该
__import__()函数必须返回“最左侧”模块对象,以便可以将其分配给
pkg。因此,这两个导入语句转换为:
pkg = __import__('pkg')pkg = __import__('pkg.mod')在第三,第四和第五种情况下,该
import语句必须做更多的工作:它必须(可能)分配多个名称,这必须从模块对象中获取。该
__import__()函数只能返回一个对象,没有真正的理由让它从模块对象中检索每个名称(这会使实现变得更加复杂。)因此,简单的方法应类似于(对于第三个)案件):
tmp = __import__('pkg')mod = tmp.modmod2 = tmp.mod2但是,如果
pkg是包,
mod或者
mod2是该包 中尚未导入的
模块(如在第三种和第五种情况下),那将不起作用。该
__import__()功能需要知道
mod和
mod2是名字的
import声明都希望能够获得访问,以便它可以看到,如果他们是模块和尝试导入他们。因此,电话更接近:
tmp = __import__('pkg', fromlist=['mod', 'mod2'])mod = tmp.modmod2 = tmp.mod2这会导致
__import__()尝试和负载
pkg.mod和
pkg.mod2以及
pkg(但如果
mod还是
mod2不存在,它不是在错误
__import__()的呼叫;产生一个错误是留给
import。声明),但还不是第四和正确的事第五个示例,因为如果调用是这样的:
tmp = __import__('pkg.mod', fromlist=['submod'])submod = tmp.submod那么
tmp最终将
pkg像以前一样是,而不是
pkg.mod您
submod要从中获取属性的模块。该实现可能已经决定要这样做,所以该
import语句会做更多的工作,
.像
__import__()已经在函数中那样拆分程序包名称并遍历名称,但这将意味着重复一些工作。所以,相反,执行方面取得
__import__()返回
最右边的 模块,而不是 最左边的 一个 当且仅当 fromlist里传递,而不是空。
(
import pkg as pand
from pkg import mod as m语法对这个故事没有任何改变,只是将本地名称分配给了它-
使用该
__import__()函数时
as并没有什么不同,它们都保留在
import语句实现中。)



