动态导入 Python 模块
最近遇到的一个问题是这样的:应用有一个 config.py 文件,在这个文件里面定义了下面这个参数:
#: Installed modules
INSTALLED_MODULES = [
{'name': 'main', 'prefix': ''},
]
这是我的一个 Flask 项目中使用到的,在我的项目中,有很多个模块,比如 user , group 等,但是我并不是在任何一个站点上都需要所有的这些模块,所以我就在配置文件里面加入了上面的配置,只有这里面的模块才被安装,并且,这里面没有的模块我就不再导入进来,所以就需要动态的导入模块了,这个时候我以前使用的 import 或者 from package import module 等都不能工作。
要解决这个问题,有两个办法,一个是使用 exec 声明,如下面这样的:
>>> sys
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'sys' is not defined
>>> s = 'import sys'
>>> exec s
>>> sys
<module 'sys' (built-in)>
这个办法可以解决,但是还有另一个更好的办法就是使用 __import__() 函数:
该函数与 import 声明很相似,但是它是一个实实在在的函数,我们可以对导入过程更加细致的控制,比如我最上面所说的需求可以像下面这样实现:
for m in INSTALLED_MODULES:
mod = __import__(m['name'])
app.register_blueprint('mod',prefix = m['prefix'])
另外,如果我们有另一个需求,需要导入一个指定的列表内的所有的模块,还可以使用一个叫做map() 的函数:
>>> module_names = ['sys','os','re','unittest']
>>> module_names
['sys', 'os', 're', 'unittest']
>>> modules = map(__import__, module_names)
>>> modules
[<module 'sys' (built-in)>, <module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>, <module 're' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.pyc'>, <module 'unittest' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/__init__.pyc'>]
>>> modules[0].version
'2.7.1 (r271:86832, Jun 16 2011, 16:59:05) n[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)]'
>>> import sys
>>> sys.version
'2.7.1 (r271:86832, Jun 16 2011, 16:59:05) n[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)]'
评论已关闭