Z pomocą poczty Guido dostarczonej przez @kindall, możemy zrozumieć standardowy proces importu jako próbę znalezienia modułu w każdym elemencie sys.pathi pliku w wyniku tego wyszukiwania (więcej szczegółów w PyMOTW Modules and Imports .). Więc jeśli moduł znajduje się na ścieżce sys.pathbezwzględnej, wynik jest bezwzględny, ale jeśli znajduje się na ścieżce względnej, sys.pathwynik jest względny.
Teraz site.pyplik startowy dba o dostarczenie tylko ścieżki bezwzględnej w sys.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 prefiksowaniem sys.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.pyw /tmp/z kodem:
import sys
print(sys.path)
print (__file__)
Jeśli wejdziesz do / tmp, otrzymasz:
>>> import foo
['', '/tmp', '/usr/lib/python3.3', ...]
./foo.py
Po wejściu /home/user, jeśli dodasz /tmpswoje PYTHONPATH, otrzymasz:
>>> import foo
['', '/tmp', '/usr/lib/python3.3', ...]
/tmp/foo.py
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.
>>> import sys
>>> sys.path.append('../../tmp')
>>> import foo
['', '/usr/lib/python3.3', .... , '../../tmp']
../../tmp/foo.py
Guido wyjaśnia w cytowanym powyżej wątku, dlaczego Python nie próbuje przekształcić wszystkich wpisów w ścieżki absolutne:
nie chcemy wywoływać getpwd () przy każdym imporcie ... getpwd () jest stosunkowo powolne i czasami może się nie powieść,
Więc twoja ścieżka jest używana taka, jaka jest .