2009-12-12 6 views
62

Un autre développeur et moi sommes en désaccord sur le fait que PYTHONPATH ou sys.path doive être utilisé pour permettre à Python de trouver un paquet Python dans un répertoire utilisateur (par exemple, développement).PYTHONPATH vs. sys.path

Nous avons un projet Python avec une structure de répertoire typique:

Project 
    setup.py 
    package 
     __init__.py 
     lib.py 
     script.py 

En script.py, nous devons faire import package.lib. Lorsque le package est installé dans des packages de site, script.py peut trouver package.lib. Lorsque vous travaillez à partir d'un répertoire utilisateur, cependant, quelque chose d'autre doit être fait. Ma solution consiste à définir mon PYTHONPATH pour inclure "~/Project". Un autre développeur veut mettre cette ligne de code au début de script.py:

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 

Alors que Python peut 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 à partir d'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?

+1

Semble que les votes et les réponses sont répartis équitablement avec une très légère tendance vers l'utilisation de PYTHON_PATH, bien qu'il puisse s'agir d'un bruit d'échantillonnage ou d'un biais involontaire de la question. – AJP

Répondre

37

Si la seule raison de modifier le chemin est que les développeurs travaillent à 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 installer l'arborescence de travail dans votre installation Python actuelle.

2

Je pense que, dans ce cas, l'utilisation de PYTHONPATH est une meilleure chose, surtout parce qu'elle n'introduit pas de code inutile (douteux).

Après tout, si vous pensez, votre utilisateur n'a pas besoin que sys.path chose, parce que votre colis s'installé dans site-packages, parce que vous allez utiliser un système d'emballage. Si l'utilisateur choisit de s'exécuter à partir d'une "copie locale", comme je l'appelle, alors j'ai observé que la pratique habituelle est d'indiquer que le paquet doit être ajouté manuellement à PYTHONPATH, s'il est utilisé à l'extérieur les paquets de site.

32

Je déteste PYTHONPATH. Je trouve cela fâcheux et ennuyeux de régler par utilisateur (en particulier pour les utilisateurs de démon) et de garder une trace de l'évolution des dossiers de projet. Je préfère placer sys.path dans les scripts invoke pour les projets autonomes.

Cependant sys.path.append n'est pas le moyen de le faire. Vous pouvez facilement obtenir des doublons et ne pas trier les fichiers .pth. Mieux (et plus lisible): site.addsitedir.

Et script.py ne serait normalement pas l'endroit le plus approprié pour le faire, car c'est à l'intérieur le paquet que vous voulez mettre à disposition sur le chemin. Les modules de la bibliothèque ne devraient certainement pas toucher eux-mêmes sys.path. Au lieu de cela, vous auriez normalement un hashbanged-script en dehors du paquet que vous utilisez pour instancier et exécuter l'application, et c'est dans ce script wrapper trivial que vous mettriez des détails de déploiement comme sys.path -frobbing.

+10

Le problème avec 'site.addsitedir' est qu'il fait un append sur' sys.path', ce qui signifie qu'un paquet installé aura préséance sur le paquet local en développement (et que le tirage des cheveux pourrait s'ensuivre). 'sys.path.insert (0 ...' est nécessaire pour surmonter cela.) –

+3

@EliBendersky: devrait être 'sys.path.insert (1'. http://stackoverflow.com/q/10095037/125507 – endolith

4

En plus des nombreuses autres raisons déjà mentionnées, vous pourriez aussi le point outh que coder en dur

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

est fragile car elle suppose l'emplacement de script.py - il ne fonctionnera que si le script .py se trouve dans Project/package. Il va se casser si un utilisateur décide de déplacer/copier/symlink script.py (presque) n'importe où ailleurs.

7

En général, je considérerais l'établissement d'une variable d'environnement (comme PYTHONPATH) comme une mauvaise pratique. Bien que cela puisse être bien pour un débogage unique, mais en utilisant cela comme
une pratique régulière pourrait ne pas être une bonne idée.

L'utilisation de la variable d'environnement conduit à des situations telles que "ça marche pour moi" quand une autre
signale des problèmes dans la base de code. De même, on pourrait avoir la même pratique avec l'environnement de test , conduisant à des situations comme les tests fonctionnant correctement pour un développeur particulier mais échouant probablement quand quelqu'un lance les tests.

Questions connexes