2009-04-20 9 views
7

Wie könnte man testen, ob eine Reihe von Modulen installiert ist, angesichts der Namen der Module. Z.B.Test auf Python-Modul Abhängigkeiten installiert werden

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

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

Während es möglich ist, als die Tests zu schreiben:

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

Dies ist ein bisschen umständlich für das, was ich tue. Gibt es einen dynamischen Weg, dies zu tun?

Ich habe versucht eval ("Import% s"% -Modul), aber das beschwerte sich über einen Kompilierungsfehler.

Ich bin dankbar für Ihre Gedanken und Anregungen. Vielen Dank.

Antwort

8

können Sie die __import__() Funktion wie diese verwenden ::

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

Sie auch imp.find_module verwenden können, um zu bestimmen, ob ein Modul es ohne Import ::

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

Oh gefunden werden kann, und der Grund, warum Sie eval() nicht verwenden können, ist, weil import eine Anweisung ist, kein Ausdruck. Sie können Verwendung exec wenn Sie wirklich wollen, obwohl ich würde es nicht empfehlen ::

for module in modules: 
    try: 
     exec 'import ' + module 
    except ImportError: 
     do_something() 
6

Was ist falsch daran?

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

Die oben verwendet die __import__ Funktion. Außerdem testet es streng, ob es existiert oder nicht - es speichert den Import nicht irgendwo, aber Sie können ihn leicht ändern, um das zu tun.

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

Es lohnt sich die Kompromisse zwischen dem find_module Ansatz zu verstehen und die __import__ Ansatz:

  • __import__('foo') werden alle Seiteneffekte des Ladens des Moduls auslösen, unabhängig davon, ob Sie einen Verweis auf das importierte Modul speichern. Das könnte OK sein oder nicht.
  • find_module('foo') wird keine Nebenwirkungen auslösen, so sollte es immer sicher sein.
  • weder Ansatz funktioniert gut, wenn das Modul gefunden wird, hat aber andere Probleme bei der Ladezeit (z. B. Syntaxerror, Nameerror, ...)
  • Je nachdem, wie Sie Ausfälle handhaben, einfach __import__('foo') in einem Try/außer Verpackung geben Sie irreführende Ergebnisse, wenn foo gefunden wird, aber foo importiert Bar, die ist nicht gefunden.
  • find_module() können gepunkteten Namen nicht umgehen, wenn Sie also, ob ‚foo.bar.bat.baz‘ müssen prüfen, importiert werden können, müssen Sie mehrere Anrufe verwenden, um find_module und load_module gemäß den docs.