Inny programista i ja nie zgadzamy się co do tego, czy PYTHONPATH lub sys.path powinny być używane, aby umożliwić Pythonowi znalezienie pakietu Pythona w katalogu użytkownika (np. Deweloperskim).
Mamy projekt w Pythonie z typową strukturą katalogów:
Project
setup.py
package
__init__.py
lib.py
script.py
W script.py musimy to zrobić import package.lib
. Gdy pakiet jest instalowany w pakietach witryn, plik script.py może znaleźć package.lib
.
Jednak podczas pracy z katalogu użytkownika należy zrobić coś innego. Moim rozwiązaniem jest ustawienie mojej PYTHONPATH tak, aby zawierała „~ / Project”. Inny programista chce umieścić tę linię kodu na początku script.py:
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
Aby Python mógł znaleźć lokalną kopię package.lib
.
Myślę, że to zły pomysł, ponieważ ta linia jest przydatna tylko dla programistów lub osób korzystających z lokalnej kopii, ale nie mogę podać dobrego powodu, dla którego jest to zły pomysł.
Czy powinniśmy użyć PYTOHNPATH, sys.path, czy też jest w porządku?
źródło
PATH
isys.path
(i pośrednioPYTHONPATH
), zobacz także stackoverflow.com/questions/25344841/sys-path-vs-pathOdpowiedzi:
Jeśli jedynym powodem modyfikacji ścieżki są programiści pracujący w ich drzewie roboczym, powinieneś użyć narzędzia instalacyjnego, aby skonfigurować swoje środowisko. virtualenv jest bardzo popularny, a jeśli używasz setuptools, możesz po prostu uruchomić,
setup.py develop
aby częściowo zainstalować drzewo robocze w bieżącej instalacji Pythona.źródło
Nienawidzę PYTHONPATH. Uważam, że ustawienie dla każdego użytkownika (szczególnie dla użytkowników demonów) i śledzenie przemieszczania się folderów projektów jest kruche i denerwujące. Wolałbym raczej ustawić
sys.path
w skryptach wywołania dla samodzielnych projektów.Jednak
sys.path.append
nie jest to sposób na zrobienie tego. Możesz łatwo uzyskać duplikaty i nie sortuje.pth
plików. Lepiej (i bardziej czytelny)site.addsitedir
.I
script.py
normalnie nie byłoby bardziej odpowiednim miejscem do zrobienia tego, ponieważ znajduje się w pakiecie, który chcesz udostępnić na ścieżce. Moduły biblioteczne z pewnością nie powinny się dotykaćsys.path
. Zamiast tego normalnie miałbyś skrypt hashbanged poza pakietem, którego używasz do tworzenia wystąpienia i uruchamiania aplikacji, i to w tym trywialnym skrypcie opakowującym umieszczasz szczegóły wdrożenia, takie jaksys.path
-frobbing.źródło
site.addsitedir
polega na tym, że działaappend
onsys.path
, co oznacza, że zainstalowany pakiet będzie miał pierwszeństwo przed pakietem lokalnym w trakcie opracowywania (i może dojść do wyrywania włosów).sys.path.insert(0...
trzeba to przezwyciężyć.sys.path.insert(1
. stackoverflow.com/q/10095037/125507Ogólnie uważam, że ustawienie zmiennej środowiskowej (takiej jak PYTHONPATH) jest złą praktyką. Chociaż może to być w porządku w przypadku jednorazowego debugowania, ale używanie tego jako
zwykłej praktyki może nie być dobrym pomysłem.
Użycie zmiennej środowiskowej prowadzi do sytuacji typu „u mnie działa”, gdy ktoś
inny zgłasza problemy w kodzie. Można również przeprowadzić tę samą praktykę w środowisku testowym, co prowadzi do sytuacji, takich jak testy, które działają dobrze dla określonego programisty, ale prawdopodobnie kończą się niepowodzeniem, gdy ktoś uruchamia testy.
źródło
Oprócz wielu innych powodów, o których już wspomniano, możesz również wskazać na to twarde kodowanie
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
jest kruchy, ponieważ zakłada lokalizację script.py - będzie działać tylko wtedy, gdy skrypt.py znajduje się w projekcie / pakiecie. Zepsuje się, jeśli użytkownik zdecyduje się przenieść / skopiować / dowiązanie symboliczne script.py (prawie) gdziekolwiek indziej.
źródło
Myślę, że w tym przypadku użycie PYTHONPATH jest lepsze, głównie dlatego, że nie wprowadza (wątpliwego) niepotrzebnego kodu.
W końcu, jeśli o tym pomyślisz, twój użytkownik tego nie potrzebuje
sys.path
, ponieważ twój pakiet zostanie zainstalowany w pakietach lokacji, ponieważ będziesz używać systemu pakowania.Jeśli użytkownik wybierze uruchomienie z "kopii lokalnej", jak to nazywasz, to zauważyłem, że zwykłą praktyką jest stwierdzenie, że pakiet musi być dodany ręcznie do PYTHONPATH, jeśli jest używany poza pakietami witryny .
źródło
Ani hakowanie,
PYTHONPATH
ani niesys.path
jest dobrym pomysłem z wyżej wymienionych powodów. A do łączenia bieżącego projektu z folderem pakietów witryn jest właściwie lepszy sposób niżpython setup.py develop
, jak wyjaśniono tutaj :pip install --editable path/to/project
Jeśli nie masz jeszcze pliku setup.py w folderze głównym swojego projektu, ten jest wystarczająco dobry, aby zacząć od:
from setuptools import setup setup('project')
źródło