Jak mogę użyć skryptu Python w linii poleceń bez konieczności przechodzenia do jego katalogu? Czy to PYTHONPATH?

157

Jak mogę wykorzystać PYTHONPATH? Kiedy próbuję uruchomić skrypt w ścieżce, plik nie zostaje znaleziony. Kiedy przechodzę do katalogu zawierającego skrypt, skrypt jest uruchamiany. Więc po co jest 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'

Po cd do katalogu plików to działa ...

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

Dlaczego nie mogę skorzystać z PYTHONPATH?

Randy Skretka
źródło
1
Czy możemy zmienić tytuł tego posta? W rzeczywistości nie jest to prośba o wyjaśnienie PYTHONPATH.
Nico Cernek
Edytowany tytuł, ponieważ jest to pierwsza rzecz, która pojawia się podczas googlowaniaPYTHONPATH
raphael

Odpowiedzi:

194

Myślę, że jesteś trochę zdezorientowany. PYTHONPATH ustawia ścieżkę wyszukiwania do importowania modułów Pythona, a nie do ich wykonywania, tak jak próbujesz.

PYTHONPATH Rozszerz domyślną ścieżkę wyszukiwania plików modułów. Format jest taki sam jak PATH powłoki: jedna lub więcej ścieżek katalogów oddzielonych przez os.pathsep (np. Dwukropki w Uniksie lub średniki w Windows). Nieistniejące katalogi są dyskretnie ignorowane.

Oprócz zwykłych katalogów, poszczególne wpisy PYTHONPATH mogą odnosić się do plików zip zawierających czyste moduły Pythona (w postaci źródłowej lub skompilowanej). Nie można importować modułów rozszerzeń z plików zip.

Domyślna ścieżka wyszukiwania jest zależna od instalacji, ale zwykle zaczyna się od przedrostka / lib / pythonversion (zobacz PYTHONHOME powyżej). Jest zawsze dołączony do PYTHONPATH.

Dodatkowy katalog zostanie wstawiony do ścieżki wyszukiwania przed PYTHONPATH, jak opisano powyżej w opcjach interfejsu. Ścieżką wyszukiwania można manipulować z poziomu programu w języku Python jako zmienną sys.path.

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

To, czego szukasz, to PATH.

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

Jednak aby uruchomić skrypt w języku Python jako program, musisz również ustawić shebang dla Pythona w pierwszym wierszu. Coś takiego powinno działać:

#!/usr/bin/env python

I nadaj mu uprawnienia do wykonywania:

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

Wtedy powinieneś być w stanie po prostu biegać gmbx.pyz dowolnego miejsca.

Pedro Werneck
źródło
2
Dziękuję przyjacielu. Nadal to rozwiązuję. Mój skrypt pomyślnie zaimportował moje moduły z mojej niestandardowej PYTHONPATH. A teraz rozumiem różnicę: chodzi o skrypt kontra moduł; wywołanie skryptu poleceń a import w języku Python. Tak, faktycznie export PATH=$PATH:/home/etc
użyję
57

Mylisz PATH i PYTHONPATH. Musisz to zrobić:

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

PYTHONPATH jest używany przez interpreter języka Python do określenia, które moduły mają zostać załadowane.

PATH jest używana przez powłokę do określenia, które pliki wykonywalne mają zostać uruchomione.

Richard
źródło
38

PYTHONPATHwpływa tylko na importinstrukcje, a nie na wyszukiwanie plików Pythona przez interpreter najwyższego poziomu podane jako argumenty.

Konieczność PYTHONPATHustawienia nie jest dobrym pomysłem - podobnie jak w przypadku wszystkiego, co zależy od zmiennych środowiskowych, konsekwentne replikowanie rzeczy na różnych maszynach staje się trudne. Lepiej jest używać „pakietów” Pythona, które można zainstalować (używając „pip” lub distutils) w ścieżkach zależnych od systemu, o których Python już wie.

Przeczytaj https://the-hitchhikers-guide-to-packaging.readthedocs.org/en/latest/ - „The Hitchhiker's Guide to Packaging”, a także http://docs.python.org/3/tutorial /modules.html - co wyjaśnia PYTHONPATH i pakiety na niższym poziomie.

kodowana struktura
źródło
Punkt zajęty. W tym konkretnym przypadku dodanie do PYTHONPATH wydaje się jednak nieźle sprawdzać. Jako jeden użytkownik na jednym komputerze mogę dobrze wykorzystać i ponownie wykorzystać już napisany kod .py.
Randy Skretka
1
Szczerze mówiąc, nie uważam, że instalowanie rzeczy w ścieżkach zależnych od systemu, z wymaganymi uprawnieniami administratora, jest lepszym pomysłem niż używanie PYTHONPATH. Nie liczę już, ile razy miałem do czynienia z prymitywnym programem w Pythonie, który nalegał na to pip install, że byłem zwykłym użytkownikiem na hoście nie tylko bez uprawnień roota (wiem, że pip może wykonać lokalną instalację), ale również bez pip. Oto rada dla wszystkich dystrybuujących oprogramowanie Python - najpierw spróbuj zainstalować własne oprogramowanie na waniliowym hoście z systemem Linux, na którym nie masz uprawnień administratora i tylko podstawową dystrybucję Pythona bez pip.
amn
3

Myślę, że jesteś pomieszany między PATH i PYTHONPATH. Wszystko, co musisz zrobić, aby uruchomić „skrypt”, to dodać jego katalog nadrzędny do zmiennej PATH. Możesz to sprawdzić, uruchamiając

which myscript.py

Ponadto, jeśli myscripy.pyzależy od modułów niestandardowych, ich katalogi nadrzędne muszą również zostać dodane do zmiennej PYTHONPATH. Niestety, ponieważ projektanci Pythona najwyraźniej używali narkotyków, testowanie importu w replik z poniższymi nie gwarantuje, że PYTHONPATH jest poprawnie ustawiony do użycia w skrypcie. Ta część programowania w Pythonie jest magiczna i nie można na nią odpowiednio odpowiedzieć w przepływie stosu.

$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
źródło
3

Z PYTHONPATH ustawionym jak w twoim przykładzie, powinieneś być w stanie to zrobić

python -m gmbx

-mopcja sprawi, że Python będzie szukał twojego modułu w ścieżkach Python zwykle przeszukuje moduły, w tym te, które dodałeś do PYTHONPATH. Kiedy uruchamiasz interpreter jak python gmbx.py, szuka on konkretnego pliku, a PYTHONPATH nie ma zastosowania.

Tigran Saluev
źródło