Как заставить скрипт читать связанные файлы внутри исполняемого zip-архива Python?
Я использую модуль zipapp из стандартной библиотеки для создания исполняемого zip-архива Python. Мне удалось связать мои файлы Python и не-Python внутри zip-файла. Однако связанные сценарии Python не могут читать другие связанные файлы. Как связанный сценарий может прочитать другой связанный файл?
Вот минимальный пример. Дерево каталогов:
.
└── src
├── __main__.py
└── text.txt
src/__main__.py
:
with open('./text.txt', 'r') as f:
print(f.read())
src/text.txt
:
The quick brown fox jumps over the lazy dog.
Это работает как ожидалось (он распечатывает текстовый файл):
cd src/
python3 __main__.py
Итак, теперь я пытаюсь создать исполняемый архив и запустить его:
python3 -m zipapp src/ -o myapp
python3 myapp
Но это дает:
Traceback (most recent call last):
File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "myapp/__main__.py", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: './text.txt'
Итак, я отредактировал src/__main__.py
использовать абсолютный путь, а не относительный:
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# Use the absolute path.
with open(os.path.join(BASE_DIR, 'text.txt'), 'r') as f:
print(f.read())
Снова объединение (python3 -m zipapp src/ -o myapp
) и снова бегом (python3 myapp
)... Это приводит к другой ошибке:
Traceback (most recent call last):
File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "myapp/__main__.py", line 5, in <module>
NotADirectoryError: [Errno 20] Not a directory: '/home/user/myproject/myapp/text.txt'
Хорошо, это означает, что Python не может получить text.txt
потому как /home/user/myproject/myapp
это исполняемый архив, а не каталог.
В конце концов, мой вопрос: как может __main__.py
в исполняемом архиве читают файлы (например, text.txt
) которые тоже находятся внутри исполняемого архива?