Pourquoi utiliser sys.path.append (chemin) au lieu de sys.path.insert (1, chemin)?

88

Edit: sur la base d'un commentaire d'Ulf Rompe, il est important d'utiliser "1" au lieu de "0" , sinon vous casserez sys.path .

Je fais du python depuis un certain temps maintenant (plus d'un an), et je ne comprends toujours pas pourquoi les gens vous recommandent de l'utiliser à la sys.path.append()place de sys.path.insert(). Laissez-moi vous démontrer.

Disons que je travaille sur un module nommé PyWorkbooks (qui est installé sur mon ordinateur), mais que je travaille simultanément sur un module différent (disons PyJob) qui intègre PyWorkbooks. Pendant que je travaille sur PyJob, je trouve des erreurs dans PyWorkbooks que je corrige, donc je voudrais importer une version de développement.

Il y a plusieurs façons de travailler sur les deux (je pourrais mettre mon projet PyWorkbooks à l'intérieur de PyJob, par exemple), mais parfois je devrai toujours jouer avec le chemin. Cependant, je ne peux pas simplement faire un sys.path.append()dans le dossier où se trouve PyWorkbooks . Pourquoi? Parce que python trouvera d'abord mes PyWorkbooks installés!

C'est pourquoi vous devez faire un sys.path.insert (1, path_to_dev_pyworkbooks)

En résumé:

sys.path.append(path_to_dev_pyworkbooks)
import PyWorkbooks # does NOT import dev pyworkbooks, imports installed one

ou:

sys.path.insert(1, path_to_dev_pyworkbooks) # based on comments you should use **1 not 0**
import PyWorkbooks # imports correct file

Cela m'a causé quelques blocages dans le passé, et j'aimerais vraiment que nous (en tant que communauté) commencions à recommander sys.path.insert(1, path), comme si vous insérez manuellement un chemin, je pense qu'il est prudent de dire que c'est le chemin que vous voulez utiliser!

Ou est-ce que j'ai quelque chose qui ne va pas? C'est une question qui me dérange parfois et je la voulais au grand jour!

Garrett Berg
la source
3
J'ai fait sys.path.insert(1, dev_folder)mais il ne trouve toujours pas le module de développement, et n'utilise que le module installé. Comment puis-je réparer ça?
endolith

Réponses:

47

Si vous avez plusieurs versions d'un package / module, vous devez utiliser virtualenv (c'est moi qui souligne):

virtualenv est un outil pour créer des environnements Python isolés.

Le problème de base traité est celui des dépendances et des versions, et indirectement des autorisations. Imaginez que vous ayez une application qui nécessite la version 1 de LibFoo, mais qu'une autre application nécessite la version 2. Comment pouvez-vous utiliser ces deux applications? Si vous installez tout dans/usr/lib/python2.7/site-packages (ou quel que soit l'emplacement standard de votre plate-forme), il est facile de se retrouver dans une situation où vous mettez à niveau involontairement une application qui ne devrait pas être mise à niveau.

Ou plus généralement, que faire si vous souhaitez installer une application et la laisser ? Si une application fonctionne, toute modification de ses bibliothèques ou des versions de ces bibliothèques peut interrompre l'application.

Et si vous ne pouvez pas installer de packages dans le global site-packages répertoire ? Par exemple, sur un hôte partagé.

Dans tous ces cas, virtualenvpeut vous aider. Il crée un environnement qui a ses propres répertoires d'installation, qui ne partage pas les bibliothèques avec d'autres environnements virtualenv (et n'accède éventuellement pas non plus aux bibliothèques installées globalement).

C'est pourquoi les gens considèrent insert(0, qu'il se trompe - c'est une solution incomplète et provisoire au problème de la gestion de plusieurs environnements.

agf
la source
Merci, je savais vaguement que quelque chose comme ça existait mais je ne l'ai pas vérifié jusqu'à présent. Donc, ce que j'aurais à faire avec cela, c'est tout exécuter depuis l'interpréteur dans l'environnement virtuel ... cela pourrait aussi fonctionner. Merci!
Garrett Berg
1
Ceci est une suggestion mais ne répond pas directement à la question (par exemple, j'ai de fortes raisons de ne pas utiliser virtualenvet je cherche en fait la réponse associée à l'OP)
javadba
@javadba Cela peut être vrai pour votre cas, mais la plupart des personnes qui posent cette question devraient utiliser venv.
agf
45

Si vous avez vraiment besoin d'utiliser sys.path.insert, pensez à laisser sys.path [0] tel quel:

sys.path.insert(1, path_to_dev_pyworkbooks)

Cela peut être important car le code tiers peut s'appuyer sur la conformité de la documentation sys.path :

Comme initialisé au démarrage du programme, le premier élément de cette liste, chemin [0], est le répertoire contenant le script qui a été utilisé pour appeler l'interpréteur Python.

Ulf Rompe
la source
13

vous confondez le concept d'ajout et de préfixe. le code suivant est en préfixe:

sys.path.insert(1,'/thePathToYourFolder/')

il place les nouvelles informations au début (enfin, en second lieu, pour être précis) de la séquence de recherche que votre interprète va parcourir. sys.path.append()met les choses à la toute fin de la séquence de recherche.

il est conseillé d'utiliser quelque chose comme virtualenvau lieu de coder manuellement vos répertoires de paquets dans le PYTHONPATHfichier à chaque fois. pour mettre en place divers écosystèmes qui séparent vos packages de site et les versions possibles de python, lisez ces deux blogs:

  1. introduction aux écosystèmes python

  2. amorçage d'environnements virtuels python

si vous décidez de suivre la voie de l'isolation de l'environnement, vous bénéficierez certainement de la recherche dans virtualenvwrapper: http://www.doughellmann.com/docs/virtualenvwrapper/

samkhan13
la source
1
Les liens «introduction aux écosystèmes python», «amorçage des environnements virtuels python» ont été supprimés, pensez à les revitaliser.
Pradeep Singh le