2009-04-20 8 views
7

Comment tester si un ensemble de modules est installé, compte tenu du nom des modules. Par exemple.Test des dépendances du module Python en cours d'installation

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

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

Bien qu'il soit possible d'écrire les essais comme:

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

C'est un peu lourd pour ce que je fais. Y a-t-il un moyen dynamique de le faire?

J'ai essayé eval ("import% s"% module) mais cela se plaignait d'une erreur de compilation.

Je vous suis reconnaissant pour vos idées et suggestions. Je vous remercie.

Répondre

8

Vous pouvez utiliser la fonction __import__() comme celui-ci ::

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

Vous pouvez également utiliser imp.find_module pour déterminer si un module se trouve sans importer ::

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

Oh, et la raison pour laquelle vous ne pouvez pas utiliser eval() est parce que import est une déclaration, pas une expression. Vous pouvez utiliser exec si vous vraiment voulez, mais je ne le recommanderais pas ::

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

Qu'est-ce qui ne va pas? La fonction __import__ est utilisée ci-dessus. En outre, il teste strictement s'il existe ou non - il ne sauvegarde pas réellement l'importation n'importe où, mais vous pouvez facilement le modifier pour le faire.

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

Il est intéressant de comprendre les compromis entre l'approche find_module et l'approche __import__:

  • __import__('foo') déclenchera les effets secondaires du chargement du module, que vous enregistrez ou non une référence au module importé. Cela pourrait être OK ou non.
  • find_module('foo') ne déclenchera aucun effet secondaire, ainsi il devrait toujours être sûr.
  • ni approche fonctionne bien si le module se trouve mais a d'autres problèmes au moment de la charge (par exemple. SyntaxError NameError, ...)
  • Selon la façon dont vous gérez les échecs, emballage simplement __import__('foo') dans un try/except donnera vous trompez les résultats si foo est trouvé mais foo importe la barre qui est pas trouvé.
  • find_module() ne peut pas gérer les noms en pointillés, donc si vous devez vérifier si « foo.bar.bat.baz » peut être importé, vous devez utiliser plusieurs appels à find_module et load_module selon le docs.
Questions connexes