测试Python模块依赖是否安装
如何测试一组模块是否已经安装,给定这些模块的名称。例如:
modules = set(["sys", "os", "jinja"])
for module in modules:
# if test(module exists):
# do something
虽然可以像这样写出测试:
try:
import sys
except ImportError:
print "No sys!"
但这样做对我来说有点麻烦。我有没有更灵活的方法来实现这个呢?
我试过使用 eval("import %s" % module),但这报了编译错误。
我很感激你们的想法和建议。谢谢。
4 个回答
5
了解使用 find_module
方法和 __import__
方法之间的利弊是很重要的:
__import__('foo')
会加载模块时触发任何副作用,不管你是否保存了这个模块的引用。这可能没问题,也可能有问题。find_module('foo')
不会触发任何副作用,所以它通常是安全的。- 如果模块找到了,但在加载时有其他问题(比如语法错误、名称错误等),这两种方法都不好使。
- 根据你处理失败的方式,如果简单地把
__import__('foo')
放在 try/except 里,如果找到了 foo 但 foo 又去导入一个没有找到的 bar,这样会给你误导性的结果。 find_module()
不能处理带点的名字,所以如果你需要检查 'foo.bar.bat.baz' 是否可以导入,你就得多次调用 find_module 和 load_module,具体可以参考 文档。
6
这段代码有什么问题呢?
modules = set(["sys", "os", "jinja"])
for m in modules:
try:
__import__(m)
except ImportError:
# do something
上面的代码使用了一个叫做 __import__
的函数。而且,它只是严格地检查这个函数是否存在,并没有真正把导入的内容保存下来。不过,你可以很简单地修改代码,让它把导入的内容保存起来。
8
你可以这样使用 __import__()
函数:
for module in modules:
try:
__import__(module)
except ImportError:
do_something()
你还可以使用 imp.find_module
来检查一个模块是否能被找到,而不需要先导入它:
import imp
for module in modules:
try:
imp.find_module(module)
except ImportError:
do_something()
哦,还有一个原因是你不能使用 eval()
,因为 import
是一个语句,而不是一个表达式。不过如果你真的想的话,可以使用 exec
,不过我不太推荐这样做:
for module in modules:
try:
exec 'import ' + module
except ImportError:
do_something()