16.6. 动态导入模块

好了,大道理谈够了。让我们谈谈动态导入模块吧。

首先,让我们看一看正常的模块导入。import module 语法查看搜索路径,根据给定的名字寻找模块并导入它们。你甚至可以这样做:以逗号分割同时导入多个模块,本章代码前几行就是这样做的。

例 16.13. 同时导入多个模块


import sys, os, re, unittest 1
1 这里同时导入四个模块:sys (为系统函数和得到命令行参数)、os (为目录列表之类的操作系统函数)、re (为正则表达式),以及 unittest (为单元测试)。

现在让我们用动态导入做同样的事。

例 16.14. 动态导入模块

>>> sys = __import__('sys')           1
>>> os = __import__('os')
>>> re = __import__('re')
>>> unittest = __import__('unittest')
>>> sys                               2
>>> <module 'sys' (built-in)>
>>> os
>>> <module 'os' from '/usr/local/lib/python2.2/os.pyc'>
1 内建 __import__ 函数与 import 语句的既定目标相同,但它是一个真正的函数,并接受一个字符串参数。
2 变量 sys 现在是 sys 模块,和 import sys 的结果完全相同。变量 os 现在是一个 os 模块,等等。

因此 __import__ 导入一个模块,但是是通过一个字符串参数来做到的。依此处讲,你用以导入的仅仅是一个硬编码性的字符串,但它可以是一个变量,或者一个函数调用的结果。并且你指向模块的变量也不必与模块名匹配。你可以导入一系列模块并把它们指派给一个列表。

例 16.15. 动态导入模块列表

>>> moduleNames = ['sys', 'os', 're', 'unittest'] 1
>>> moduleNames
['sys', 'os', 're', 'unittest']
>>> modules = map(__import__, moduleNames)        2
>>> modules                                       3
[<module 'sys' (built-in)>,
<module 'os' from 'c:\Python22\lib\os.pyc'>,
<module 're' from 'c:\Python22\lib\re.pyc'>,
<module 'unittest' from 'c:\Python22\lib\unittest.pyc'>]
>>> modules[0].version                            4
'2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)]'
>>> import sys
>>> sys.version
'2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)]'
1 moduleNames 只是一个字符串列表。没什么特别的,只是这些名字刚好是你可应需而用的可导入模块名。
2 简单得令人惊奇,通过映射 __import__ 就实现了导入。记住,列表 (moduleNames) 的每个元素将被用来一次次调用函数 (__import__) 并以一个返回值构成的列表作为返回结果。
3 所以现在你已经由一个字符串列表构建起了一个实际模块的列表。(你的路径可能不同,这取决于你的操作系统、你安装 Python 的位置、月亮残缺的程度等等。)
4 从这些是真实模块这一点出发,让我们来看一些模块属性。记住,modules[0] sys 模块,因此,modules[0].version sys.version。所有模块的其他属性和方法也都可用。import 语句没什么神奇的,模块也没什么神奇的。模块就是对象,一切都是对象。

现在,你应该能够把这一切放在一起,并搞清楚本章大部分样例代码是做什么的。