С помощью почты Гвидо, предоставленной @kindall, мы можем понять стандартный процесс импорта как попытку найти модуль в каждом элементе sys.path
и файл в результате этого поиска (подробнее в Модули и импорт PyMOTW .).Поэтому, если модуль находится в абсолютном пути в sys.path
, результат является абсолютным, но если он находится в относительном пути в sys.path
, результат является относительным.
Теперь файл запуска site.py
заботится о доставке только абсолютного пути в sys.path
, кроме начального ''
, поэтому, если вы не измените его другими способами, кроме установки PYTHONPATH (путь которого также сделан абсолютным, перед префиксом sys.path
), выбудет всегда получать абсолютный путь, но когда к модулю обращаются через текущий каталог.
Теперь, если вы обманываете sys.path забавным способом, вы можете получить что угодно.
Например, если выесть пример модуля foo.py
в /tmp/
с кодом:
import sys
print(sys.path)
print (__file__)
Если вы войдете в / tmp, вы получите:
>>> import foo
['', '/tmp', '/usr/lib/python3.3', ...]
./foo.py
Когда в в /home/user
, есливы добавляете /tmp
ваше PYTHONPATH
вы получаете:
>>> import foo
['', '/tmp', '/usr/lib/python3.3', ...]
/tmp/foo.py
Даже если вы добавите ../../tmp
, оно будет нормализовано и результат будет таким же.
Но если вместоиспользуя PYTHONPATH
, вы используете какой-то забавный путь, вы получаете такой же забавный результат, как и причина.
>>> import sys
>>> sys.path.append('../../tmp')
>>> import foo
['', '/usr/lib/python3.3', .... , '../../tmp']
../../tmp/foo.py
Гвидо объясняет в цитированной выше теме, почему python не пытается преобразовать все записи в абсолютные пути:
нам не нужно вызывать getpwd ()при каждом импорте .... getpwd () является относительно медленным и иногда может напрямую потерпеть неудачу,
Таким образом, ваш путь используется как .