web-dev-qa-db-fra.com

Gestion des erreurs lors de l'importation de modules

Cela a probablement une réponse évidente, mais je suis un débutant. J'ai un "module" (vraiment juste un fichier avec un tas de fonctions que j'utilise souvent) au début duquel j'importe un certain nombre d'autres modules. Parce que je travaille sur de nombreux systèmes, cependant, tous les modules ne peuvent pas être chargés sur une machine particulière. Pour rendre les choses un peu plus difficiles, je change également les noms des paquets lorsque je les importe - par exemple, matplotlib est abrégé en mp.

Ce que j'aimerais faire, c'est seulement charger les modules qui existent sur le système que j'utilise actuellement, et faire une gestion des erreurs sur ceux qui n'en ont pas. La seule façon d'y penser est de placer chaque instruction d'importation dans son propre bloc try, ce qui semble assez anti-Pythonic. Si je les enferme tous dans le même bloc d'essai, le module qui lance une erreur empêchera le chargement des modules suivants. Des idées qui pourraient rendre les choses plus jolies? Ce serait si facile si je ne voulais pas changer leurs noms ...

37
Dave Schultz

Je ne pense pas try except le bloc n'est pas Pythonic; c'est plutôt une façon courante de gérer l'importation sur Python.

Citant Plongez dans Python :

Il existe de nombreuses autres utilisations des exceptions en plus de la gestion des conditions d'erreur réelles. Une utilisation courante dans la bibliothèque standard Python est d'essayer d'importer un module, puis de vérifier s'il a fonctionné . L'importation d'un module qui n'existe pas déclenchera une exception ImportError. Vous pouvez l'utiliser pour définir plusieurs niveaux de fonctionnalités en fonction des modules disponibles au moment de l'exécution ou pour prendre en charge plusieurs plates-formes (où le code spécifique à la plate-forme est séparé en différents modules ).

L'exemple suivant montre comment utiliser une exception pour prendre en charge des fonctionnalités spécifiques à la plate-forme.

try:
    import termios, TERMIOS                     
except ImportError:
    try:
        import msvcrt                           
    except ImportError:
        try:
            from EasyDialogs import AskPassword 
        except ImportError:
            getpass = default_getpass           
        else:                                   
            getpass = AskPassword
    else:
        getpass = win_getpass
else:
    getpass = unix_getpass
48
systempuntoout

Comme préconisé par https://stackoverflow.com/a/20228312/1587329 [modifié, avec une modification de @Ian]

from importlib import import_module

named_libs = [('numpy', 'np'), ('matplotlib', 'mp')] # (library_name, shorthand)
for (name, short) in named_libs:
    try:
        lib = import_module(name)
    except:
        print sys.exc_info()
    else:
        globals()[short] = lib

importe toutes les bibliothèques dans named_libs. La première chaîne est le nom de la bibliothèque, la seconde la sténographie. Pour les bibliothèques sans nom, vous pouvez utiliser l'original :

from importlib import import_module     

libnames = ['numpy', 'scipy', 'operator']
for libname in libnames:
    try:
        lib = import_module(libname)
    except:
        print sys.exc_info()
    else:
        globals()[libname] = lib
7
serv-inc

Le moyen le plus simple consiste à s'assurer que tous les modules peuvent être chargés sur tous les systèmes. Si cela ne fonctionne pas, enfermer chaque instruction import dans un bloc try est la meilleure solution suivante et pas du tout non-Pythonic.

4
Philipp