Тест для устанавливаемых зависимостей модуля Python - PullRequest
7 голосов
/ 20 апреля 2009

Как можно проверить, установлен ли набор модулей, с учетом названий модулей. Э.Г.

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 ]

8 голосов
/ 20 апреля 2009

Вы можете использовать функцию __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()
6 голосов
/ 20 апреля 2009

Что с этим не так?

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

Выше используется функция __import__. Кроме того, он строго проверяет, существует ли он или нет - он фактически не сохраняет импорт, но вы можете легко изменить его, чтобы сделать это.

5 голосов
/ 14 июля 2010

Стоит понять компромиссы между подходом find_module и подходом __import__:

  • __import__('foo') вызовет любые побочные эффекты загрузки модуля, независимо от того, сохраните ли вы ссылку на импортированный модуль. Это может быть нормально, или нет.
  • find_module('foo') не вызывает побочных эффектов, поэтому всегда должно быть безопасно.
  • Ни один из подходов не работает хорошо, если модуль найден, но есть другие проблемы во время загрузки (например, SyntaxError, NameError, ...)
  • В зависимости от того, как вы справляетесь со сбоями, простое завершение __import__('foo') в попытке / исключении даст вам вводящие в заблуждение результаты, если найден foo, но строка импорта foo, которая не найдена.
  • find_module() не может обрабатывать точечные имена, поэтому, если вам необходимо проверить, можно ли импортировать файл 'foo.bar.bat.baz', вам нужно использовать несколько вызовов для find_module и load_module согласно документам .
2 голосов
/ 20 апреля 2009
modules = set(["sys", "os", "jinja"])
try:
  for module in modules:
    __import__(module)
  doSomething()
except ImportError, e:
    print e
...