Использование --onefile
объединяет все данные вместе в файл .exe
.
При запуске файла эти файлы «распаковываются» во временную папку. На Windows это обычно C:\Users\<You>\AppData\Local\Temp\MEIxxx
.
Итак, когда вы разрабатываете свой скрипт, файлы данных (ваши текстовые файлы в этом примере) будут расположены по адресу
C:\\Users\\%username%\\PycharmProjects\\%project_folder%\\%project_folder%\txt_files\
но при компиляции приложения они будут извлечены во временный каталог, упомянутый выше. Таким образом, вам нужен способ сообщить сценарию, разрабатываете ли вы его или он был скомпилирован. Здесь вы можете использовать флаг 'замороженного' (см. Документы здесь)
Подход, который я использовал ранее, заключается в создании вспомогательной функции, подобной этой
def resolve_path(path):
if getattr(sys, "frozen", False):
# If the 'frozen' flag is set, we are in bundled-app mode!
resolved_path = os.path.abspath(os.path.join(sys._MEIPASS, path))
else:
# Normal development mode. Use os.getcwd() or __file__ as appropriate in your case...
resolved_path = os.path.abspath(os.path.join(os.getcwd(), path))
return resolved_path
Затем, когда вы захотите использовать путь в вашем скрипте, например, для доступа к вашим текстовым файлам, вы можете сделать
with open(resolve_path("txt_files/file1.txt"), "r") as txt:
...
, который должен определить правильный путь, в каком бы режиме вы ни находились.
Примечание к вашему .spe c файлу
- Вам не нужно указывать все текстовые файлы по отдельности. Вы можете, конечно, и у вас может быть веская причина для этого, и это хорошо. Но вы можете сделать
datas=[('txt_files', '.')]
, который поместит содержимое каталога txt_files
в root вашего пакета. Однако будьте осторожны с этим, поскольку теперь пути к вашим текстовым файлам будут <dev directory>\txt_files\file1.txt
, но в прилагаемом приложении они будут <MEIPASS directory>\file1.txt
. Возможно, вы захотите сохранить «относительную» часть пути тем же, выполнив
datas=[('txt_files', 'txt_files')]
, который будет отражать файловую структуру между вашей папкой разработки и приложенным приложением.
Также подумайте, что если вы строите с файлом spe c, удалите часть
COLLECT
, чтобы получить исполняемый файл в комплекте с одним файлом.