Python“嵌入式”打包中的文件夹结构
我在Windows上分发一个可以直接运行的软件,这个软件是用Python写的,具体步骤如下:
- 把一个嵌入版的Python内容打包,比如说
python-3.8.10-embed-amd64.zip
- 添加一个
myprogram\
文件夹(也就是程序本身) - 只需运行
pythonw.exe -m myprogram
就可以启动程序
这样做效果很好(而且比起cxfreeze等工具,这种方法简单多了,不过这部分不在这里讨论)。
文件结构是这样的:
main\
_asyncio.pyd
_bz2.pyd
... + other .pyd files
libcrypto-1_1.dll
... + other .dll files
python.exe
pythonw.exe
python38._pth
python38.zip
...
myprogram\ # here my main program as a module
PIL\ # dependencies
win32\
numpy\
... # many other folders for dependencies
有没有办法把所有依赖的文件夹移动到一个子文件夹里,同时让Python(嵌入版)仍然能找到它们?怎么做呢? 更具体地说,像这样:
main\
python.exe
pythonw.exe
python38._pth
python38.zip
...
myprogram\ # here my main program as a module
dependencies\
PIL\ # all required modules
win32\
numpy\
...
_asyncio.pyd # and also .pyd files
...
注意:这里的目标是使用一个嵌入版的Python,它是与系统全局安装的Python完全独立的。所以这和任何环境变量,比如 PYTHONPATH
等都没有关系。
1 个回答
有没有办法把所有的依赖文件夹移动到一个子文件夹里,同时让Python(嵌入版)继续工作呢?
可以的。依赖文件其实可以安装在任何地方,只要包含它们的文件夹在PYTHONPATH里就行(具体可以查看这个链接:PYTHONPATH)。
提问者后来补充说:
注意:这里的目标是使用一个嵌入式Python,它完全独立于系统的全局Python安装。所以这和任何环境变量,比如PYTHONPATH等都没有关系。
在这种情况下,第三方的依赖依然可以安装在任何子文件夹里。根据一位Python核心开发者的说法,你应该可以把这个文件夹添加到._pht文件中:
嵌入式包是为你无法控制的环境设计的,所以你需要隔离。如果你想导入一个site-packages文件夹,只需把它添加到._pth文件中,它就会被包含在sys.path里(https://discuss.python.org/t/add-a-command-line-parameter-to-add-folders-to-sys-path-needed-for-embedded-python/28426/10)
这些信息在Python文档中也可以找到:
对于那些想把Python打包到他们的应用程序或发行版中的人,以下建议可以防止与其他安装产生冲突:
在你的可执行文件旁边包含一个._pth文件,里面列出要包含的目录。这将忽略注册表和环境变量中列出的路径,也会忽略site,除非列出了import site。
(https://docs.python.org/3.12/using/windows.html#windows-embeddable)
但是如果你只是想运行 pythonw.exe -m myprogram
,那么这并不是在一个隔离的沙盒环境中运行,也不清楚为什么在这种情况下要使用特别的嵌入式Python版本。这绝对不是嵌入式Python的典型用法。