Я использовал для открытия файлов, которые были в том же каталоге, что и текущий скрипт 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]))
кажется, вернуть каталог скриптов. Я не уверен, есть ли разница между этими двумя.
Редактировать:
Я просто понял, что то, что я хочу сделать, лучше описать как «открыть файл в том же каталоге, что и содержащий модуль». Другими словами, если я импортирую написанный мной модуль, который находится в другом каталоге, и этот модуль открывает файл, я хочу, чтобы он искал файл в каталоге модуля. Я не думаю, что что-то, что я нашел, может это сделать ...
__file__
нельзя использовать, используйтеsys.argv[0]
вместоdirname(__file__)
. Остальное должно работать как положено. Мне нравится использовать,__file__
потому что в коде библиотеки,sys.argv[0]
может вообще не указывать на ваш код, особенно если он импортирован через какой-то сторонний скрипт.realpath( join( getcwd(), dirname(__file__) ))
описанного здесь?Цитировать из документации Python:
sys.path [0] - это то, что вы ищете.
источник
os.path.join(sys.path[0], 'some file.txt')
. Это должно правильно обрабатывать пробелы и косые черты во всех системах.Хорошо, вот что я делаю
sys.argv - это всегда то, что вы вводите в терминал или используете в качестве пути к файлу при выполнении его с помощью python.exe или pythonw.exe
Например, вы можете запустить файл text.py несколькими способами, каждый из которых даст вам свой ответ, он всегда даст вам путь, по которому был набран python.
Итак, знайте, что вы можете получить имя файла, большое дело, теперь, чтобы получить каталог приложения, который вы знаете, используйте os.path, в частности, abspath и dirname
Это выведет это:
это всегда будет выводиться независимо от того, введете ли вы python test.py или python «C: \ Documents and Settings \ Admin \ test.py»
Проблема с использованием __file__ Рассмотрим эти два файла test.py
import_test.py
Вывод "python test.py"
Вывод "python test_import.py"
Итак, как вы видите, файл всегда дает вам файл python, из которого он запускается, а sys.argv [0] дает вам файл, который вы всегда запускали из интерпретатора. В зависимости от ваших потребностей вам нужно будет выбрать тот, который лучше всего соответствует вашим потребностям.
источник
__file__
как предполагается , чтобы «всегда даст вам путь к текущему файлу», иsys.argv[0]
как предполагается , чтобы «всегда дают путь к сценарию , который инициировал процесс». В любом случае, использование__file__
в вызываемом скрипте всегда дает точные результаты.__file__
на верхний уровень скрипта, он будет работать как положено.Я смог успешно использовать код, предоставленный dcolish, так как у меня была похожая проблема с чтением определенного текстового файла. Файл не находится в том же CWD, что и файл Python.
источник
Я бы сделал это так:
Приведенный выше код создает абсолютный путь к файлу с использованием abspath и эквивалентен использованию
normpath(join(os.getcwd(), path))
[это из pydocs]. Затем он проверяет, существует ли этот файл на самом деле, а затем использует диспетчер контекста, чтобы открыть его, чтобы вам не пришлось вспоминать о вызове close для дескриптора файла. ИМХО, делая это таким образом, вы избавите вас от боли в долгосрочной перспективе.источник
os.path.abspath
не разрешает пути к файлам в той же папке, что и скрипт, если скрипт не находится в текущем каталоге.