测试Python模块依赖是否安装

7 投票
4 回答
4072 浏览
提问于 2025-04-15 11:11

如何测试一组模块是否已经安装,给定这些模块的名称。例如:

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()

撰写回答