я использовал, чтобы открыть файлы, которые были в том же каталоге, что и в настоящее время работает скрипт на Python, просто используя командуКак надежно открыть файл в том же каталоге, что и сценарий Python
open("Some file.txt", "r")
Однако я обнаружил, что, когда сценарий запускался в Windows, дважды щелкнув его, он попытается открыть файл из неправильного каталога.
С тех пор я использовал команду вида
open(os.path.join(sys.path[0], "Some file.txt"), "r")
всякий раз, когда я хотел, чтобы открыть файл. Это работает для моего конкретного использования, но я не уверен, что sys.path[0]
может потерпеть неудачу в некоторых других случаях использования.
Итак, мой вопрос: что является лучшим и надежным способом открыть файл, который находится в том же каталоге, что и текущий запущенный скрипт Python?
Вот что я смог выяснить до сих пор:
os.getcwd()
иos.path.abspath('')
вернуть «текущий рабочий каталог», а не каталог скриптов.os.path.dirname(sys.argv[0])
иos.path.dirname(__file__)
возвращают путь, используемый для вызова сценария, который может быть относительным или даже пустым (если скрипт находится в cwd). Кроме того,__file__
не существует, когда сценарий запускается в IDLE или PythonWin.sys.path[0]
иos.path.abspath(os.path.dirname(sys.argv[0]))
, кажется, возвращают каталог сценария. Я не уверен, есть ли разница между этими двумя.
Edit:
Я просто понял, что я хочу сделать, лучше было бы описать как «открыть файл в том же каталоге, содержащего модуль». Другими словами, если я импортирую модуль, я написал, что это в другом каталоге, и этот модуль открывает файл, я хочу, чтобы он искал файл в каталоге модуля. Я не думаю, что я нашел в состоянии сделать это ...
Если '__file__' не может быть использован, используйте' sys.argv [0] 'вместо' dirname (__ file __) '. Остальное должно работать так, как ожидалось. Мне нравится использовать '__file__', потому что в библиотечном коде' sys.argv [0] 'может не указывать на ваш код вообще, особенно если он импортируется через какой-то сторонний скрипт. –
Проблема с этим заключается в том, что он будет меняться, если вы запускаете файл из прерывателя напрямую или если он импортируется. См. Мой ответ за различия между __file__ и sys.argv [0] – Zimm3r
. Правильно ли говорить, что вариант, описанный в ответе Zimm3r, адресуется с помощью 'realpath (join (getcwd(), dirname (__ file__)))' as описанный здесь? – pianoJames