Comment puis-je utiliser un script Python dans la ligne de commande sans cd-ing dans son répertoire? Est-ce le PYTHONPATH?

157

Comment puis-je utiliser PYTHONPATH? Lorsque j'essaie d'exécuter un script dans le chemin, le fichier n'est pas trouvé. Lorsque je cd dans le répertoire contenant le script, le script s'exécute. Alors à quoi sert le PYTHONPATH?

$ echo $PYTHONPATH
:/home/randy/lib/python

$ tree -L 1 '/home/randy/lib/python' 
/home/randy/lib/python
├── gbmx_html.py
├── gbmx.py
├── __init__.py
├── __pycache__
├── scripts
└── yesno.py

$ python gbmx.py -h
python: can't open file 'gbmx.py': [Errno 2] No such file or directory

$ cd '/home/randy/lib/python'

Après le cd dans le répertoire de fichiers, il s'exécute.

$ python gbmx.py -h
usage: gbmx.py [-h] [-b]

Pourquoi ne puis-je pas utiliser le PYTHONPATH?

Randy Skretka
la source
1
Pouvons-nous changer le titre de cet article? Il ne s'agit pas vraiment de demander une explication PYTHONPATH.
Nico Cernek
Titre modifié parce que c'est la première chose qui apparaît lors de la recherche sur GooglePYTHONPATH
Raphael

Réponses:

194

Je pense que vous êtes un peu confus. PYTHONPATH définit le chemin de recherche pour importer des modules python, pas pour les exécuter comme vous essayez.

PYTHONPATH Augmente le chemin de recherche par défaut des fichiers de module. Le format est le même que le PATH du shell: un ou plusieurs chemins de répertoire séparés par os.pathsep (par exemple deux points sous Unix ou des points-virgules sous Windows). Les répertoires inexistants sont ignorés en silence.

En plus des répertoires normaux, les entrées individuelles PYTHONPATH peuvent faire référence à des fichiers zip contenant des modules Python purs (sous forme source ou compilée). Les modules d'extension ne peuvent pas être importés à partir de fichiers zip.

Le chemin de recherche par défaut dépend de l'installation, mais commence généralement par le préfixe / lib / pythonversion (voir PYTHONHOME ci-dessus). Il est toujours annexé à PYTHONPATH.

Un répertoire supplémentaire sera inséré dans le chemin de recherche devant PYTHONPATH comme décrit ci-dessus sous Options d'interface. Le chemin de recherche peut être manipulé à partir d'un programme Python en tant que variable sys.path.

http://docs.python.org/2/using/cmdline.html#envvar-PYTHONPATH

Ce que vous recherchez, c'est PATH.

export PATH=$PATH:/home/randy/lib/python 

Cependant, pour exécuter votre script python en tant que programme, vous devez également définir un shebang pour Python dans la première ligne. Quelque chose comme ça devrait fonctionner:

#!/usr/bin/env python

Et donnez-lui des privilèges d'exécution:

chmod +x /home/randy/lib/python/gbmx.py

Ensuite, vous devriez pouvoir simplement courir gmbx.pyde n'importe où.

Pedro Werneck
la source
2
Merci mon ami. Je suis toujours en train de régler ça. Mon script réussit à importer mes modules depuis mon PYTHONPATH personnalisé. Et maintenant je comprends la différence: tout est question de script par rapport à module; appel de script de commande contre importation python. Oui, je vais en fait utiliserexport PATH=$PATH:/home/etc
Randy Skretka
57

Vous confondez PATH et PYTHONPATH. Vous devez faire ceci:

export PATH=$PATH:/home/randy/lib/python 

PYTHONPATH est utilisé par l'interpréteur python pour déterminer les modules à charger.

PATH est utilisé par le shell pour déterminer les exécutables à exécuter.

Richard
la source
38

PYTHONPATHn'affecte que les importinstructions, pas la recherche de l'interpréteur Python de niveau supérieur des fichiers Python donnés en arguments.

Le besoin PYTHONPATHd'être défini n'est pas une bonne idée - comme pour tout ce qui dépend de variables d'environnement, répliquer les choses de manière cohérente sur différentes machines devient difficile. Mieux vaut utiliser des 'packages' Python qui peuvent être installés (en utilisant 'pip' ou distutils) dans des chemins dépendants du système que Python connaît déjà.

Lisez https://the-hitchhikers-guide-to-packaging.readthedocs.org/en/latest/ - 'The Hitchhiker's Guide to Packaging', ainsi que http://docs.python.org/3/tutorial /modules.html - qui explique PYTHONPATH et les packages à un niveau inférieur.

structure codée
la source
Point pris. Dans ce cas particulier, l'ajout de PYTHONPATH semble bien fonctionner. En tant qu'utilisateur sur une machine, je peux bien utiliser et réutiliser du code .py déjà écrit.
Randy Skretka
1
Honnêtement, je ne pense pas qu'installer des choses dans des chemins dépendants du système, avec un accès root requis, soit une meilleure idée que d'utiliser PYTHONPATH. Je ne compte plus le nombre de fois où j'ai dû faire face à un programme Python rudimentaire qui insistait sur le pip installfait que j'étais un utilisateur régulier sur un hôte non seulement sans accès root (je sais que pip peut faire une installation locale) mais également sans pip. Voici un conseil à tous ceux qui distribuent des logiciels Python - essayez d'abord d'installer votre propre logiciel sur un hôte Linux vanille où vous n'avez pas d'accès root et uniquement la distribution principale de Python sans pip.
amn le
3

Je pense que vous êtes confondu entre PATH et PYTHONPATH. Tout ce que vous avez à faire pour exécuter un «script» est d'ajouter son répertoire parental à votre variable PATH. Vous pouvez tester cela en exécutant

which myscript.py

De plus, si cela myscripy.pydépend de modules personnalisés, leurs répertoires parentaux doivent également être ajoutés à la variable PYTHONPATH. Malheureusement, comme les concepteurs de python étaient clairement sur les médicaments, tester vos importations dans la réplique avec ce qui suit ne garantira pas que votre PYTHONPATH est correctement défini pour une utilisation dans un script. Cette partie de la programmation python est magique et ne peut pas trouver de réponse appropriée sur stackoverflow.

$python
Python 2.7.8 blahblahblah
...
>from mymodule.submodule import ClassName
>test = ClassName()
>^D
$myscript_that_needs_mymodule.submodule.py
Traceback (most recent call last):
  File "myscript_that_needs_mymodule.submodule.py", line 5, in <module>
    from mymodule.submodule import ClassName
  File "/path/to/myscript_that_needs_mymodule.submodule.py", line 5, in <module>
    from mymodule.submodule import ClassName
ImportError: No module named submodule
W4t3randWind
la source
3

Avec PYTHONPATH défini comme dans votre exemple, vous devriez pouvoir faire

python -m gmbx

-mCette option permettra à Python de rechercher votre module dans les chemins dans lesquels Python recherche généralement les modules, y compris ce que vous avez ajouté à PYTHONPATH. Lorsque vous exécutez l'interpréteur comme python gmbx.py, il recherche un fichier particulier et PYTHONPATH ne s'applique pas.

Tigran Saluev
la source