Этот ответ предназначен для Linux и Python3 (Python 3.7), основная идея та же для Windows / MacOS, но некоторые детали могут отличаться.
Поскольку venv
используется, у нас есть следующие опции:
- добавление
<..>/sometest/lib/python3.5/site-packages
(sometest
в качестве корневой папки виртуальной среды) к sys.path
либо программно в pyx-файле, либо путем установки переменной PYTHONPATH
-environment перед запуском.
- размещение исполняемого файла с внедренным python в подкаталоге
sometest
(например, bin
или создание собственного).
- с использованием
virtualenv
вместо venv
.
Примечание. Для исполняемого файла с внедренным питоном он не играет никакой роли, независимо от того, активирована виртуальная среда (или какая) или нет.
Почему вышеописанное работает в вашем сценарии?
Проблема в том, что (встроенный) Python-интерпретатор должен выяснить, где находятся следующие вещи:
- независимый от платформы каталог / файлы, например, «Os.py
,
argparse.py (mostly everything *.py/*.pyc). Given [
sys.prefix ][1], the interpreter can figure out where to find them (i.e. in
префикс / Lib / pythonX.Y`).
- каталог / файлы, зависящие от платформы, например, общие библиотеки. Учитывая
sys.exec_prefix
, интерпретатор может выяснить, где их найти (например, общие библиотеки можно найти в exec_prefix/lib/pythonX.Y/lib-dynload
).
Алгоритм может быть найден здесь , и поиск выполняется, когда выполняется Py_Initialize
. Когда эти каталоги найдены, можно создать `sys.path '.
Однако при использовании venv
рядом с exe или в родительском каталоге имеется pyvenv.cfg
-файл *1052*, который гарантирует, что найден правильный Python-Home - хорошая отправная точка home
ключ в этом файле.
Когда используется site.py
(он может быть найден интерпретатором, поскольку известно sys.prefix
) для добавления дополнительных пакетов виртуальной среды к sys.path
, site.py
ищет pyvenv.cfg
и разбирает. Тем не менее, локальные side-packages
добавляются в путь Python только тогда, когда:
Если файл с именем "pyvenv.cfg" существует на один каталог выше
sys.executable, sys.prefix и sys.exec_prefix установлены на это
каталог и он также проверяется на наличие пакетов сайта (sys.base_prefix
и sys.base_exec_prefix всегда будут «настоящими» префиксами
Установка Python).
В вашем случае pyvenv.cfg
находится не в указанном выше каталоге, а в том же, что и exe - поэтому локальные пакеты сайта, где библиотеки были установлены через pip, не включены. Глобальные пакеты сайта не включены, потому что pyvenv.cfg
имеет ключ include-system-site-packages = false
. Таким образом, не допускаются дополнительные пакеты, и установленные библиотеки не могут быть найдены.
Однако перемещение каталога exe на один вниз приведет к включению локальных пакетов сайта в путь.
Возможны и другие сценарии, в которых учитывается местоположение исполняемого файла, а не какая среда активирована.
A: Исполняемый файл находится где-то, но не внутри виртуальной среды
Эта эвристика поиска работает более или менее надежно для установленных интерпретаторов Python, но может относиться к встроенным интерпретаторам или виртуальным средам (см. эту проблему для получения дополнительной информации).
Если python был установлен с использованием обычного apt install
или подобного, то он будет найден (из-за 4. Step в алгоритме поиска), и установка системы будет использоваться встроенным интерпретатором.
Однако, если файлы были перемещены или Python был собран из источника, но не установлен, встроенный интерпретатор не может запуститься:
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
Fatal Python error: initfsencoding: unable to load the file system codec
ModuleNotFoundError: No module named 'encodings'
В этом случае Py_SetPythonHome
или установка переменной среды $PYTHONHOME
являются возможными решениями.
B: Исполняемый файл в виртуальной среде, созданный с помощью virtualenv
Предполагая, что это одна и та же версия Python для виртуальной среды и встраиваемого Python (в противном случае мы имеем вышеупомянутый случай), emebeded exe будет использовать локальные сторонние пакеты. Алгоритм поиска домов всегда найдет местный дом, благодаря этому правилу :
Шаг 3. Попробуйте найти префикс и exec_prefix относительно argv0_path, возвращая путь до тех пор, пока он не будет исчерпан.Это самый распространенный шаг к успеху.Обратите внимание, что если префикс и exec_prefix различаются, exec_prefix с большей вероятностью будет найден;однако, если exec_prefix является подкаталогом префикса, будут найдены оба.
В этом случае argv0_path
- это путь к exe (файла pyvenv.cfg
нет!), а "landmarks" (lib / python $ VERSION / os.py и lib / python $ VERSION / lib-dynload) будут найдены, потому что они представлены в виде символических ссылок в local-home над exe.
C: Исполняемые две папки в глубине venv
-окружения
Если две, а не одна папка (там, где она работает) в venv
-среде, приведет кA: pyvenv.cfg
файл не читается при поиске дома (слишком далеко выше), в средах 'venv` отсутствуют символические ссылки на "ориентиры" (присутствуют только сторонние пакеты), и такой шаг 3 завершится неудачно, с 4.step является единственной надеждой.
Следствие: Embeded Python не будет работать без правильной установки Python, если только среди других возможностей:
необходимые файлы упакованы в lib\pythonX.Y\*
рядом с исполняющим файлом для встраивания или где-то выше (и нет pyvenv.cfg
вокруг, чтобы испортить поиск).
или pyvenv.cfg
используется для указания переводчика в нужное место.