106 votes

PEP8 - import pas en haut du fichier avec sys.path

Problème

PEP8 a une règle à propos de mettre les importations en haut d'un fichier:

Les importations sont toujours placé au début du fichier, juste après n'importe quel module, les commentaires et les docstrings, et avant de module globals et constantes.

Cependant, dans certains cas, j'aimerais faire quelque chose comme:

import sys
sys.path.insert("..", 0)

import my_module

Dans ce cas, l' pep8 utilitaire de ligne de commande de drapeaux mon code:

E402 module niveau de l'importation n'est pas au top de fichier

Quelle est la meilleure façon d'atteindre PEP8 conformité avec sys.path modifications?

Pourquoi

J'ai ce code parce que je suis en suivant la structure d'un projet donné dans Le Routard de Python.

Ce guide suggère que j'ai un my_module le dossier, un document distinct de l' tests le dossier, les deux sont dans le même répertoire. Si je veux accéder my_module de tests, je pense que j'ai besoin d'ajouter .. de la sys.path

112voto

astorga Points 496

S'il n'y a que quelques importations, vous pouvez simplement ignorer PEP8 sur ces lignes import :

 import sys
sys.path.insert("..", 0)
import my_module  # noqa
 

71voto

Roland Smith Points 10392

Souvent, j'ai plusieurs fichiers avec des tests dans un sous-répertoire foo/tests de mon projet, alors que les modules que je suis en essais sont en foo/src. Pour exécuter les tests à partir d' foo/tests sans erreurs d'import-je créer un fichier foo/tests/pathmagic.py qui ressemble à ceci;

"""Path hack to make tests work."""

import os
import sys

bp = os.path.dirname(os.path.realpath('.')).split(os.sep)
modpath = os.sep.join(bp + ['src'])
sys.path.insert(0, modpath)

Dans chaque fichier de test, j'utilise ensuite

import pathmagic  # noqa

comme la première importation. Le "noqa" commentaire empêche pycodestyle/pep8 de se plaindre d'un solde non utilisé de l'importation.

12voto

Peuchele Points 136

Il existe une autre solution de contournement.

 import sys
... all your other imports...

sys.path.insert("..", 0)
try:
    import my_module
except:
    raise
 

4voto

itsadok Points 12971

J'ai juste eu du mal avec une question similaire, et je crois que j'ai trouvé un peu plus agréable à la solution que l'on a accepté la réponse.

Créer un pathmagic module qui fait tout le sys.chemin de la manipulation, mais faire le changement à l'intérieur d'un gestionnaire de contexte:

"""Path hack to make tests work."""

import os
import sys

class context:
    def __enter__(self):
        bp = os.path.dirname(os.path.realpath('.')).split(os.sep)
        modpath = os.sep.join(bp + ['src'])
        sys.path.insert(0, modpath)

    def __exit__(self, *args):
        pass

Ensuite, dans vos fichiers de test (ou partout où vous avez besoin de cela), vous faites:

import pathmagic

with pathmagic.context():
    import my_module
    # ...

De cette façon, vous n'obtenez pas de plaintes de flake8/pycodestyle, vous n'avez pas besoin de commentaire particulier, et la structure semble avoir du sens.

Pour plus de propreté, d'envisager effectivement revenir le chemin d'accès dans l' __exit__ bloc, mais cela peut causer des problèmes avec lazy importations (si vous installez le module de code en dehors du contexte), alors peut-être n'en vaut pas la peine.


EDIT: Viens de voir beaucoup plus simple tour dans une réponse à une autre question: ajouter assert pathmagic sous votre importations pour éviter l' noqa commentaire.

3voto

user312016 Points 1923

Pour vous conformer à pep8, vous devez inclure votre chemin de projet dans le chemin python afin d'effectuer des importations relatives / absolues.

Pour ce faire, vous pouvez consulter la réponse suivante: Ajouter en permanence un répertoire à PYTHONPATH

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X