通常,Python解释器不是“独立的”,并且要运行它,需要其标准库(例如
ctypes(已编译)或
site.py(解释)),还
numpy必须设置指向其他站点包的路径(例如)。
尽管可以通过冻结py-modules并将所有c扩展名合并)到生成的可执行文件中来使Python插入器完全独立,但更容易为嵌入的插入器提供所需的安装。可以从python-
homepage(至少对于Windows)下载“标准”安装所需的文件。
有时找不到标准的模块/站点包不是开箱即用的:必须通过设置Python路径来帮助解释器,即通过在pyx文件中以编程方式添加
<..>/sometest/lib/python3.5/site-packages(
sometest作为虚拟环境根文件夹)
sys.path或
PYTHONPATH在启动之前设置-environment变量。
继续阅读以获取更多详细信息和替代解决方案。
这个答案适用于Linux和Python3(Python 3.7),基本思想与Windows / MacOS相同,但某些细节可能有所不同。
因为
venv使用,所以有以下替代方法可以解决此问题:
- 在pyx文件中以编程方式添加
<..>/sometest/lib/python3.5/site-packages
(sometest
是虚拟环境根文件夹)sys.path
或通过PYTHONPATH
在启动之前设置-environment变量来添加。 - 将带有嵌入式python的可执行文件放置在的子目录中
sometest
(例如,bin
或创建一个自己的子目录)。 - 使用
virtualenv
代替venv
。
注意:对于带有嵌入式python的可执行文件,无论是否激活了虚拟环境(或哪个虚拟环境),它都不会发挥任何作用。
为什么以上解决了您的情况下的问题?
问题是,(嵌入式)Python解释器需要弄清楚以下几点:
- 平台无关的目录/文件,例如
os.py
,argparse.py
(大多数都是* .py / * .pyc)。给定sys.prefix
,解释器可以弄清楚在哪里可以找到它们(例如prefix/lib/pythonX.Y
)。 - 平台相关的目录/文件,例如共享库。给定
sys.exec_prefix
的解释器可以弄清楚在哪里可以找到它们(例如,可以在中找到共享库exec_prefix/lib/pythonX.Y/lib-dynload
)。
可以在此处找到算法并在执行时
Py_Initialize执行搜索。一旦找到这些目录,便
sys.path可以构建。
但是,使用时
venv,exe旁边或父目录中有一个
pyvenv.cfg-file
,可确保找到正确的Python- Home-一个好的起点是此文件中的-
key。
home
如果
Py_NoSiteFlag未设置,
Py_Initialize则将利用
site.py(可以通过解释器找到它,因为
sys.prefix是已知的)或更精确
site.main()地将虚拟环境的站点包添加到中
sys.path。这样做时,
site.py查找
pyvenv.cfg并解析它。但是,
site-packages仅在以下情况下将local添加到python-path:
如果一个名为“
pyvenv.cfg”的文件位于sys.executable之上,则sys.prefix和sys.exec_prefix设置为该目录,并且还会检查该站点包(sys.base_prefix和sys.base_exec_prefix将始终是Python安装的“真实”前缀)。
您的情况
pyvenv.cfg不在上面的目录中,而是与exe相同-
因此,不包括通过pip安装库的本地站点软件包。不包含全局站点程序包,因为
pyvenv.cfg具有key
include-system-site-packages = false。因此,不允许使用站点包,也无法找到已安装的库。
但是,将exe下移一个目录会导致将本地站点程序包包含到路径中。
还有其他可能的情况,最重要的是可执行文件的位置,而不是激活哪个环境。
答:可执行文件在某处,但不在虚拟环境中
这种搜索启发式方法对于已安装的python解释器而言或多或少可靠,但对于嵌入式解释器或虚拟环境可能有所帮助(有关更多信息,请参见此问题)。
如果使用常规
apt install或类似方法安装了python
,则将找到它(由于搜索算法中的4.步骤),并且嵌入式解释器将使用系统安装。
但是,如果文件被移动或python是从源代码构建而未安装的,则嵌入的interperter无法启动:
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 precModuleNotFoundError: No module named 'encodings'
在这种情况下,
Py_SetPythonHome或设置环境变量
$PYTHONHOME是可能的解决方案。
B:可在虚拟环境中执行,由virtualenv创建
假设它与虚拟环境使用相同的Python版本,并且嵌入了python(否则,我们遇到了上述情况),那么exe将使用本地包。由于以下规则,房屋搜索算法将始终找到本地房屋:
步骤3.尝试找到相对于argv0_path的前缀和exec_prefix,回溯路径,直到耗尽为止。这是成功的最常见步骤。请注意,如果prefix和exec_prefix不同,则更有可能找到exec_prefix。但是,如果exec_prefix是prefix的子目录,则将两者都找到。
在这种情况下,
argv0_path是exe的路径(没有
pyvenv.cfg文件!),并且将找到“地标”(lib
/ python $ VERSION / os.py和lib / python $ VERSION / lib-
dynload),因为它们是在exe上方的本地住宅中以符号链接的形式显示。
C:在venv
-environment内的两个可执行文件夹
venv如果
pyvenv.cfg在搜索home(太远)时未读取文件A ,则在-
environment中向下移动两个文件夹(而不是在其中工作的文件夹)会导致’venv`-environments缺少指向“地标”的符号链接(仅本地)存在侧面包装),则第3步将失败,而第4步是唯一的希望。
结论: 如果没有正确的Python安装,嵌入式Python将无法工作,除非有其他可能性:
所需的文件被打包到
libpythonX.Y*
嵌入可执行文件的旁边或上方(并且pyvenv.cfg
周围没有混乱的搜索内容)。或
pyvenv.cfg
用于将口译员指向正确的位置。



