为什么Python的__import__需要fromlist?
问题内容:
在Python中,如果要以编程方式导入模块,则可以执行以下操作:
module = __import__('module_name')
如果要导入子模块,您会认为这很简单:
module = __import__('module_name.submodule')
当然,这是行不通的。你只是module_name
再次得到。你所要做的:
module = __import__('module_name.submodule', fromlist=['blah'])
为什么?fromlist
只要它不是空的,它的实际值就似乎无关紧要。要求参数然后忽略其值的意义何在?
Python中的大多数内容似乎都是有充分理由的,但是出于我的一生,对于这种行为的存在,我无法提出任何合理的解释。
问题答案:
实际上,的行为__import__()
完全是由于import
调用的执行__import__()
。基本上有五种不同的__import__()
调用方式import
(有两个主要类别):
import pkg
import pkg.mod
from pkg import mod, mod2
from pkg.mod import func, func2
from pkg.mod import submod
在第一种 和 第二种情况下,该import
语句应将“最左侧”模块对象分配给“最左侧”名称:pkg
。之后,import pkg.mod
您可以执行pkg.mod.func()
该操作,因为该import
语句引入了本地名称pkg
,这是具有mod
属性的模块对象。因此,该__import__()
函数必须返回“最左侧”模块对象,以便可以将其分配给pkg
。因此,这两个导入语句转换为:
pkg = __import__('pkg')
pkg = __import__('pkg.mod')
在第三,第四和第五种情况下,该import
语句必须做更多的工作:它必须(可能)分配多个名称,这必须从模块对象中获取。该__import__()
函数只能返回一个对象,没有真正的理由让它从模块对象中检索每个名称(这会使实现变得更加复杂。)因此,简单的方法应类似于(对于第三个)案件):
tmp = __import__('pkg')
mod = tmp.mod
mod2 = tmp.mod2
但是,如果pkg
是包,mod
或者mod2
是该包 中尚未导入的
模块(如在第三种和第五种情况下),那将不起作用。该__import__()
功能需要知道mod
和mod2
是名字的import
声明都希望能够获得访问,以便它可以看到,如果他们是模块和尝试导入他们。因此,电话更接近:
tmp = __import__('pkg', fromlist=['mod', 'mod2'])
mod = tmp.mod
mod2 = 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 p
andfrom pkg import mod as m
语法对这个故事没有任何改变,只是将本地名称分配给了它-
使用该__import__()
函数时as
并没有什么不同,它们都保留在import
语句实现中。)