Python“嵌入式”打包中的文件夹结构

1 投票
1 回答
45 浏览
提问于 2025-04-14 16:52

我在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 个回答

-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的典型用法。

撰写回答