Un autre développeur et moi ne sommes pas d'accord sur le fait que PYTHONPATH ou sys.path devraient être utilisés pour permettre à Python de trouver un package Python dans un répertoire utilisateur (par exemple, développement).
Nous avons un projet Python avec une structure de répertoires typique:
Project
setup.py
package
__init__.py
lib.py
script.py
Dans script.py, nous devons le faire import package.lib
. Lorsque le package est installé dans site-packages, script.py peut trouver package.lib
.
Cependant, lorsque vous travaillez à partir d'un répertoire utilisateur, quelque chose d'autre doit être fait. Ma solution est de configurer mon PYTHONPATH pour inclure "~ / Project". Un autre développeur souhaite mettre cette ligne de code au début de script.py:
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
Pour que Python puisse trouver la copie locale de package.lib
.
Je pense que c'est une mauvaise idée, car cette ligne n'est utile que pour les développeurs ou les personnes exécutant une copie locale, mais je ne peux pas donner une bonne raison pour laquelle c'est une mauvaise idée.
Devrions-nous utiliser PYTOHNPATH, sys.path, ou est-ce bien?
Réponses:
Si la seule raison de modifier le chemin est pour les développeurs travaillant à partir de leur arbre de travail, vous devez utiliser un outil d'installation pour configurer votre environnement pour vous. virtualenv est très populaire, et si vous utilisez setuptools, vous pouvez simplement exécuter
setup.py develop
pour semi-installer l'arborescence de travail dans votre installation Python actuelle.la source
Je déteste PYTHONPATH. Je trouve qu'il est fragile et ennuyeux de définir par utilisateur (en particulier pour les utilisateurs de démons) et de suivre l'évolution des dossiers de projet. Je préfère de loin définir
sys.path
dans les scripts d'invocation pour les projets autonomes.Cependant, ce
sys.path.append
n'est pas la façon de le faire. Vous pouvez facilement obtenir des doublons et cela ne trie pas les.pth
fichiers. Mieux (et plus lisible):site.addsitedir
.Et
script.py
ce ne serait normalement pas l'endroit le plus approprié pour le faire, car il se trouve à l' intérieur du package que vous souhaitez rendre disponible sur le chemin. Les modules de la bibliothèque ne devraient certainement pas se touchersys.path
. Au lieu de cela, vous auriez normalement un script hashbanged en dehors du package que vous utilisez pour instancier et exécuter l'application, et c'est dans ce script wrapper trivial que vous mettez des détails de déploiement commesys.path
-frobbing.la source
site.addsitedir
est qu'il fait unappend
onsys.path
, ce qui signifie qu'un paquet installé aura la priorité sur le paquet local dans le développement (et il peut en résulter un tirage de cheveux).sys.path.insert(0...
est nécessaire pour surmonter cela.sys.path.insert(1
. stackoverflow.com/q/10095037/125507En général, je considérerais la mise en place d'une variable d'environnement (comme PYTHONPATH) comme une mauvaise pratique. Bien que cela puisse convenir pour un débogage ponctuel, l'utiliser comme
une pratique régulière peut ne pas être une bonne idée.
L'utilisation de la variable d'environnement conduit à des situations comme «ça marche pour moi» quand quelqu'un d'
autre signale des problèmes dans la base de code. On peut également appliquer la même pratique avec l'environnement de test, conduisant à des situations telles que les tests s'exécutant correctement pour un développeur particulier, mais échouant probablement lorsque quelqu'un lance les tests.
la source
Je pense que dans ce cas, utiliser PYTHONPATH est une meilleure chose, principalement parce qu'il n'introduit pas de code inutile (discutable).
Après tout, si vous y pensez, votre utilisateur n'a pas besoin de cette
sys.path
chose, car votre package sera installé dans les packages de site, car vous utiliserez un système de packaging.Si l'utilisateur choisit de s'exécuter à partir d'une "copie locale", comme vous l'appelez, alors j'ai observé que la pratique habituelle est de déclarer que le package doit être ajouté manuellement à PYTHONPATH, s'il est utilisé en dehors des packages du site .
la source
Outre les nombreuses autres raisons déjà mentionnées, vous pouvez également souligner que le codage en dur
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
est fragile car il suppose l'emplacement de script.py - cela ne fonctionnera que si script.py se trouve dans Project / package. Il se cassera si un utilisateur décide de déplacer / copier / symlink script.py (presque) n'importe où ailleurs.
la source
Ni le piratage
PYTHONPATH
nisys.path
n'est une bonne idée pour les raisons mentionnées précédemment. Et pour lier le projet actuel dans le dossier site-packages, il existe en fait un meilleur moyen quepython setup.py develop
, comme expliqué ici :pip install --editable path/to/project
Si vous n'avez pas encore de setup.py dans le dossier racine de votre projet, celui-ci est assez bon pour commencer:
la source