Я попытаюсь решить несколько вариантов и по этому вопросу:
- нахождение пути вызываемого скрипта
- нахождение пути выполняемого в данный момент скрипта
- поиск каталога вызываемого скрипта
(Некоторые из этих вопросов были заданы на SO, но были закрыты как дубликаты и перенаправлены здесь.)
Предостережения об использовании __file__
Для импортированного вами модуля:
import something
something.__file__
вернет абсолютный путь модуля. Однако, учитывая следующий сценарий foo.py:
#foo.py
print '__file__', __file__
Вызов его с помощью 'python foo.py' вернет просто 'foo.py'. Если вы добавите шебанг:
#!/usr/bin/python
#foo.py
print '__file__', __file__
и вызовите его с помощью ./foo.py, он вернет './foo.py'. Вызов его из другого каталога (например, поместите foo.py в строку каталога), затем вызов либо
python bar/foo.py
или добавление шебанга и непосредственное выполнение файла:
bar/foo.py
вернет 'bar / foo.py' ( относительный путь).
Поиск в каталоге
Теперь перейдя оттуда к каталогу, os.path.dirname(__file__)
также может быть сложным. По крайней мере, в моей системе она возвращает пустую строку, если вы вызываете ее из того же каталога, что и файл. напр.
# foo.py
import os
print '__file__ is:', __file__
print 'os.path.dirname(__file__) is:', os.path.dirname(__file__)
выведет:
__file__ is: foo.py
os.path.dirname(__file__) is:
Другими словами, он возвращает пустую строку, поэтому это не кажется надежным, если вы хотите использовать его для текущего файла (в отличие от файла импортируемого модуль). Чтобы обойти это, вы можете обернуть это в вызов abspath:
# foo.py
import os
print 'os.path.abspath(__file__) is:', os.path.abspath(__file__)
print 'os.path.dirname(os.path.abspath(__file__)) is:', os.path.dirname(os.path.abspath(__file__))
который выводит что-то вроде:
os.path.abspath(__file__) is: /home/user/bar/foo.py
os.path.dirname(os.path.abspath(__file__)) is: /home/user/bar
Обратите внимание, что abspath () НЕ разрешает символические ссылки. Если вы хотите сделать это, используйте вместо этого realpath (). Например, создание символической ссылки file_import_testing_link, указывающей на file_import_testing.py, со следующим содержимым:
import os
print 'abspath(__file__)',os.path.abspath(__file__)
print 'realpath(__file__)',os.path.realpath(__file__)
выполнение напечатает абсолютные пути что-то вроде:
abspath(__file__) /home/user/file_test_link
realpath(__file__) /home/user/file_test.py
file_import_testing_link -> file_import_testing.py
Использование inspect
@ SummerBreeze упоминает использование модуля inspect .
Похоже, это хорошо работает и довольно кратко для импортированных модулей:
import os
import inspect
print 'inspect.getfile(os) is:', inspect.getfile(os)
послушно возвращает абсолютный путь. Однако, чтобы найти путь к исполняемому в данный момент скрипту, я не нашел способа его использовать.