Как заставить скрипт читать связанные файлы внутри исполняемого 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) которые тоже находятся внутри исполняемого архива?

0 ответов

Другие вопросы по тегам