2015-11-18 1 views
2

Je travaille sur un grand programme Python qui utilise une multitude de modules en fonction des options de la ligne de commande, en particulier, numpy. Nous avons récemment trouvé un besoin de l'exécuter sur un petit module intégré qui empêche l'utilisation de numpy. De notre point de vue, c'est assez facile (n'utilisez pas les options de ligne de commande problématiques.)PEP 8 et importation différée

Cependant, en suivant PEP 8, notre import numpy est au début de chaque module qui pourrait en avoir besoin, et le programme se bloque en raison à numpy n'étant pas installé. La solution directe consiste à déplacer import numpy du début du fichier vers les fonctions qui en ont besoin. La question est: «À quel point cela est-il mauvais?

(Une autre solution consiste à envelopper import numpy dans un try .. except. Est-ce mieux?)

+1

Puisqu'il s'agit d'une opinion, j'opterais pour 'essayer ... sauf' où j'utilise le module optionnel. Cela serait utile si vous enveloppez les informations sur le cas d'utilisation du module optionnel i.e 'numpy' dans votre cas. – sagarchalise

Répondre

1

Voici un meilleur modèle de pratique pour vérifier si un module est installé et assurez branche de code selon elle.

# GOOD 
import pkg_resources 

try: 
    pkg_resources.get_distribution('numpy') 
except pkg_resources.DistributionNotFound: 
    HAS_NUMPY = False 
else: 
    HAS_NUMPY = True 
    # You can also import numpy here unless you want to import it inside the function 

Procédez ainsi dans chaque module d'importation ayant une dépendance molle à numpy. More information in Plone CMS coding conventions.

+0

Devrais-je m'inquiéter des importations circulaires lors de l'importation de bibliothèques? (Très intéressant! +1) –

+0

C'est pourquoi nous n'attrapons pas 'ImportError' qui est une mauvaise pratique à cause de cela et quelques autres pièges comme les dépendances natives explosent –

+0

Mais peut-il exploser dans la plupart des cas? Je peux comprendre que cela puisse arriver lors de l'importation de choses depuis votre propre module ... mais pas lors de l'importation de numpy (ou d'autres bibliothèques externes). –

1

Un autre idiome que je l'ai vu est d'importer le module comme Aucun si disponible:

try: 
    import numpy as np 
except ImportError: 
    np = None 

Ou, as in the other answer, vous pouvez utiliser le pkg_resources.get_distribution ci-dessus, plutôt que d'essayer/sauf (voir the blog post liés à du plone docs).

De cette façon, avant d'utiliser numpy vous pouvez cacher l'utilisation de numpy dans un si bloc:

if np: 
    # do something with numpy 
else: 
    # do something in vanilla python 

Le clé est d'assurer que vos tests de CI ont des environnements - avec et sans numpy (et si vous testez la couverture, le bloc doit être considéré comme couvert).