Pyinstaller,只打包部分使用的第三方包,其余在另一台PC上调用

Pyinstaller, only packing part of the employed third-party packages, and calling the remaining on another PC

  1. 在 PC1 上,我有一个程序,其中使用了包 A B C,我会 喜欢用Pyinstaller把程序和A B包一起打包 (由于某种原因不包括 C),获得“main.exe”。
  2. 假设有另一台机器 PC2 安装了 python 和 包C,希望运行这个“main.exe”(没有包C embedded) on PC2,调用PC2安装的C包。

这个可以实现吗?以及如何?

我在 PC1 上通过以下方式打包程序:pyinstaller main.py --exclude-module C 并且正如预期的那样,无法在 PC2 上使用 ModuleNotFoundError: No module named 'C' 执行 main.exe,因为安装在 PC2 上的包 C 无法被识别main.exe.

确切地说,提到的包C指的是“geatpy”http://geatpy.com,包A、B指的是Numpy,Pandas,xlwt等。将所有这些打包成一个包,然后运行安装它,出现一些错误:

Traceback (most recent call last):
  File "main.py", line 9, in <module>
    from optimization import *  
  File "PyInstaller\loader\pyimod03_importers.py", line 540, in exec_module
  File "optimization.py", line 20, in <module>
    import geatpy as ea  
  File "PyInstaller\loader\pyimod03_importers.py", line 540, in exec_module
  File "geatpy\__init__.py", line 16, in <module>
ModuleNotFoundError: No module named 'awGA'
[48140] Failed to execute script main

在咨询了这个模块的开发者后,他建议将这个模块排除在包中,而是通过 pip cmd 安装,因为 pyinstaller 可能无法很好地兼容 pyd/dll 文件。我对编码很陌生,所以我可能无法理解他的意思或者可能存在一些误解。

最后,我找到了一个解决方案,将文件夹 Python38\Lib\site-packages\geatpy 中的所有 .pyd 文件手动复制到 pyinstaller 生成的文件夹 dist\main 中,我对其他几个遗漏的 .pyd 文件也是这样做的。 py 模块在执行期间发出警告。

要生成 dist\main 文件夹,应用 pyinstaller -c main.py 而不是将其捆绑到一个可执行文件中。

正如buran所说,缺少导入问题是由于pyinstaller无法检测到需要什么,尤其是.pyd文件。

我为 pyinstaller 尝试了一些其他参数但失败了,例如:--paths=.... --hidden-import=geatpy。也许这是pyinstaller的局限性。

对于buran的第二个建议,我还没有尝试过,但相信是可行的。