PEP8 a pour règle de placer les importations en haut d'un fichier:
Les importations sont toujours placées en haut du fichier, juste après les commentaires de module et les docstrings, et avant les globales et les constantes de module.
Cependant, dans certains cas, je pourrais vouloir faire quelque chose comme:
import sys
sys.path.insert("..", 0)
import my_module
Dans ce cas, l'utilitaire de ligne de commande pep8
Signale mon code:
L'importation de module E402 n'est pas en haut du fichier
Quel est le meilleur moyen d’obtenir la conformité PEP8 avec les modifications de sys.path
?
J'ai ce code parce que je suis la structure du projet donné dans Le Guide de l'auto-stoppeur en Python .
Ce guide suggère que j’ai un dossier my_module
Distinct du dossier tests
, qui se trouvent tous deux dans le même répertoire. Si je veux accéder à my_module
À partir de tests
, je pense que je dois ajouter ..
Au sys.path
Souvent, j'ai plusieurs fichiers avec des tests dans un sous-répertoire foo/tests
de mon projet, alors que les modules que je teste sont dans foo/src
. Pour exécuter les tests à partir de foo/tests
sans erreur d'importation, je crée un fichier foo/tests/pathmagic.py
ça ressemble à ça;
"""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 commentaire "noqa" empêche pycodestyle
/pep8
de se plaindre d'une importation non utilisée.
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: E402
Il existe une autre solution de contournement.
import sys
... all your other imports...
sys.path.insert("..", 0)
try:
import my_module
except:
raise
Je viens juste de me débattre avec une question similaire, et je pense avoir trouvé une solution légèrement plus intéressante que la réponse acceptée.
Créez un module pathmagic
qui effectue la manipulation sys.path, mais apportez la modification dans 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 en avez besoin), vous effectuez les tâches suivantes:
import pathmagic
with pathmagic.context():
import my_module
# ...
De cette manière, flake8/pycodestyle ne se plaint pas, vous n'avez pas besoin de commentaires particuliers et la structure semble avoir du sens.
Pour plus de netteté, envisagez de réellement inverser le chemin dans le __exit__
block, bien que cela puisse causer des problèmes avec les imports paresseux (si vous placez le code du module en dehors du contexte), cela ne vaut peut-être pas la peine.
[~ # ~] edit [~ # ~] : Je viens de voir un truc beaucoup plus simple dans un réponse à une question différente : ajouter assert pathmagic
sous vos importations pour éviter le commentaire noqa
.
Avez-vous déjà essayé ce qui suit:
import sys
from importlib import import_module
sys.path.insert("..", 0)
# import module
my_mod = import_module('my_module')
# get method or function from my_mod
my_method = getattr(my_mod , 'my_method')
Pour vous conformer à pep8, vous devez inclure votre chemin de projet dans le chemin python) afin de pouvoir effectuer des importations relatives/absolues.
Pour ce faire, vous pouvez consulter la réponse suivante: Ajouter définitivement un répertoire à PYTHONPATH