7

How could one test whether a set of modules is installed, given the names of the modules. E.g.

modules = set(["sys", "os", "jinja"])

for module in modules:
  # if test(module exists):
  #   do something

While it's possible to write out the tests as:

try:
  import sys
except ImportError:
  print "No sys!"

This is a bit cumbersome for what I'm doing. Is there a dynamic way to do this?

I've tried eval("import %s"%module) but that complained of a compile error.

I'm grateful for your thoughts and suggestions. Thank you.

4 Answers 4

8

You can use the __import__() function like this::

for module in modules:
    try:
        __import__(module)
    except ImportError:
        do_something()

You can also use imp.find_module to determine whether a module can be found without importing it::

import imp
for module in modules:
    try:
        imp.find_module(module)
    except ImportError:
        do_something()

Oh, and the reason you can't use eval() is because import is a statement, not an expression. You can use exec if you really want to, though I wouldn't recommend it::

for module in modules:
    try:
        exec 'import ' + module
    except ImportError:
        do_something()
Sign up to request clarification or add additional context in comments.

Comments

6

What's wrong with this?

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

The above uses the __import__ function. Also, it is strictly testing whether it exists or not - its not actually saving the import anywhere, but you could easily modify it to do that.

Comments

5

It's worth understanding the tradeoffs between the find_module approach and the __import__ approach:

  • __import__('foo') will trigger any side effects of loading the module, regardless of whether you save a reference to the imported module. That might be OK, or not.
  • find_module('foo') won't trigger any side effects, so it should always be safe.
  • neither approach works well if the module is found but has other problems at load time (eg. SyntaxError, NameError, ...)
  • Depending on how you handle failures, simply wrapping __import__('foo') in a try/except will give you misleading results if foo is found but foo imports bar which is not found.
  • find_module() can't handle dotted names, so if you need to check whether 'foo.bar.bat.baz' can be imported, you have to use multiple calls to find_module and load_module as per the docs.

Comments

2
modules = set(["sys", "os", "jinja"])
try:
  for module in modules:
    __import__(module)
  doSomething()
except ImportError, e:
    print e

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.