7

给定模块的名称,如何测试是否安装了一组模块。例如

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

4 回答 4

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()
于 2009-04-20T14:43:12.823 回答
6

这有什么问题?

modules = set(["sys", "os", "jinja"])
for m in modules:
    try:
        __import__(m)
    except ImportError:
        # do something

以上使用该__import__功能。此外,它正在严格测试它是否存在 - 它实际上并未将导入保存在任何地方,但您可以轻松修改它来做到这一点。

于 2009-04-20T14:31:51.480 回答
5

值得了解 find_module 方法和__import__方法之间的权衡:

  • __import__('foo')无论您是否保存对导入模块的引用,都会触发加载模块的任何副作用。这可能是好的,也可能不是。
  • find_module('foo')不会引发任何副作用,因此它应该始终是安全的。
  • 如果找到模块但在加载时存在其他问题(例如 SyntaxError、NameError ......),则两种方法都无法正常工作
  • 根据您处理失败的方式,如果找到了 foo 但 foo 导入了__import__('foo')找到的 bar,则简单地包装在 try/except 中会给您带来误导性的结果。
  • find_module()无法处理带点的名称,因此如果您需要检查是否可以导入“foo.bar.bat.baz”,则必须根据文档对 find_module 和 load_module 进行多次调用。
于 2010-07-14T16:05:14.747 回答
2
modules = set(["sys", "os", "jinja"])
try:
  for module in modules:
    __import__(module)
  doSomething()
except ImportError, e:
    print e
于 2009-04-20T14:43:22.467 回答