Mam problem ze zrozumieniem __file__
. Z tego co rozumiem __file__
zwraca bezwzględną ścieżkę, z której moduł został załadowany.
Mam problem z utworzeniem tego: mam abc.py
jedno oświadczenie print __file__
, biegnące od /d/projects/
python abc.py
zwrotów abc.py
. ucieczka przed /d/
zwrotami projects/abc.py
. Jakieś powody, dlaczego?
Odpowiedzi:
Z dokumentacji :
Z wątku listy mailingowej, do którego prowadzi @kindall w komentarzu do pytania:
W pozostałej części
sys.path
nie uwzględniaj''
.Tak więc, jeśli jesteś poza częścią,
sys.path
która zawiera moduł, otrzymasz bezwzględną ścieżkę . Jeśli jesteś wewnątrz częścisys.path
zawierającej moduł, otrzymasz ścieżkę względną .Jeśli załadować moduł w bieżącym katalogu, a bieżący katalog nie jest w
sys.path
, dostaniesz ścieżki bezwzględnej.Jeśli załadujesz moduł w bieżącym katalogu, a bieżący katalog się w nim znajduje
sys.path
, otrzymasz ścieżkę względną.źródło
sys.path
, dostaniesz ścieżki bezwzględnej. Jeśli załadujesz moduł w bieżącym katalogu, a bieżący katalog się w nim znajdujesys.path
, otrzymasz ścieżkę względną.sys.path
nie zawiera''
.__file__
jest bezwzględne od Pythona 3.4 , z wyjątkiem wykonywania skryptu bezpośrednio przy użyciu ścieżki względnej:Nie jestem pewien, czy rozwiązuje jednak linki symboliczne.
Przykład przekazania ścieżki względnej:
źródło
Python 3.4.0 (default, Apr 11 2014, 13:05:11) [GCC 4.8.2] on linux
). A linki symboliczne nie są rozwiązywane w moich próbach.os.path.realpath(__file__)
właściwy sposób rozwiązywania dowiązań symbolicznych?Późny prosty przykład:
W Python-2. * Drugie wywołanie nieprawidłowo określa na
path.abspath(__file__)
podstawie bieżącego katalogu:Jak zauważył @techtonik, w Pythonie 3.4+ będzie to działać dobrze, ponieważ
__file__
zwraca ścieżkę bezwzględną.źródło
__main__
modułu, gdzie__file__
może być ścieżką względną.Z pomocą poczty Guido dostarczonej przez @kindall, możemy zrozumieć standardowy proces importu jako próbę znalezienia modułu w każdym elemencie
sys.path
i pliku w wyniku tego wyszukiwania (więcej szczegółów w PyMOTW Modules and Imports .). Więc jeśli moduł znajduje się na ścieżcesys.path
bezwzględnej, wynik jest bezwzględny, ale jeśli znajduje się na ścieżce względnej,sys.path
wynik jest względny.Teraz
site.py
plik startowy dba o dostarczenie tylko ścieżki bezwzględnej wsys.path
, poza początkową''
, więc jeśli nie zmienisz jej w inny sposób niż ustawienie PYTHONPATH (której ścieżka również jest bezwzględna, przed prefiksowaniemsys.path
), zawsze otrzymasz bezwzględną path, ale gdy dostęp do modułu odbywa się za pośrednictwem bieżącego katalogu.Jeśli oszukasz sys.path w zabawny sposób, możesz uzyskać wszystko.
Jako przykład, jeśli masz moduł próbki
foo.py
w/tmp/
z kodem:Jeśli wejdziesz do / tmp, otrzymasz:
Po wejściu
/home/user
, jeśli dodasz/tmp
swojePYTHONPATH
, otrzymasz:Nawet jeśli dodasz
../../tmp
, zostanie znormalizowany, a wynik będzie taki sam.Ale jeśli zamiast użyć
PYTHONPATH
, użyjesz bezpośrednio jakiejś zabawnej ścieżki, otrzymasz wynik tak zabawny, jak przyczyna.Guido wyjaśnia w cytowanym powyżej wątku, dlaczego Python nie próbuje przekształcić wszystkich wpisów w ścieżki absolutne:
Więc twoja ścieżka jest używana taka, jaka jest .
źródło