pyinstaller 创建的 exe 文件,运行 时找不到自定义模块

exe-file created by pyinstaller, not find self-defined modules while running

我创建了两个python文件,directory/file关系如下:

mytest---
     |---mycommon.py
     |---myMainDir---
                     |----myMain.py

在mycommon.py中:

def myFunc(a):
    ...

并且在 myMain.py 中:

import sys
sys.path.append(os.path.join(os.path.dirname(os.path.abspath('__file__')), '..'))
import mycommon.py
mycommon.myFunc("abc")

然后我使用 pyinstaller 创建了 exe:

pyinstall.py -F mytest\myMainDir\myMain.py

MyMain.exe 已创建,但当 运行 时,提示无法找到 mycommon 模块。

PyInstaller官方手册describes本期:

Some Python scripts import modules in ways that PyInstaller cannot detect: for example, by using the __import__() function with variable data, or manipulating the sys.path value at run time. If your script requires files that PyInstaller does not know about, you must help it.

还有suggests遇到这种情况应该怎么办:

If Analysis recognizes that a module is needed, but cannot find that module, it is often because the script is manipulating sys.path. The easiest thing to do in this case is to use the --paths= option to list all the other places that the script might be searching for imports:

pyi-makespec --paths=/path/to/thisdir --paths=/path/to/otherdir myscript.py

这些路径将在分析过程中添加到当前 sys.path

因此,请在构建应用程序时指定 --paths 参数。指定 -p 参数的手册 states 等效于:

-p dir_list, --paths=dir_list

Set the search path(s) for imported modules (like using PYTHONPATH). Use this option to help PyInstaller to search in the right places when your code modifies sys.path for imports. Give one or more paths separated by ; (under Windows) or : (all other platforms), or give the option more than once to give multiple paths to search.

此外,我不得不努力让 pyinstaller 正确地在子文件夹中导入 python 脚本,子文件夹的路径是通过 sys.path.insert.

相对设置的

Yoel 的回答对我来说是正确的,但我需要在 Windows 中仔细设置路径。这是我所做的:

我的主要py是:

D:\_Development\pCompareDBSync\pCompareDBSync\pCompareDBSync.py

我导入的py是:

D:\_Development\pCompareDBSync\pCompareDBSync\py\pCompareNVR.py

(我在文件夹 .\py\ 中有很多这样的导入 py,但这里我只使用一个作为示例)

所以我的主要PY,我有以下内容:

sys.path.insert(0, 'py')

try:
    from pCompareNVR import fgetNV_sN_dict
    from pCompareNVR import findNVRJobInDBSync
    from pCompareNVR import getNVRRecords
    from pCompareNVR import saveNVRRecords
    from pCompareNVR import compareNVRs
except Exception as e:
    print('Can not import files:' + str(e))
    input("Press Enter to exit!")
    sys.exit(0)

pyinstaller --onefile pCompareDBSync.py 

-> pCompareDBSync.exe 不包括 py/pCompareNVR.py

我必须在主 PY 和导入的 PY 中包含绝对填充:

pyinstaller --onefile --paths=D:\_Development\pCompareDBSync\pCompareDBSync\ --paths=D:\_Development\pCompareDBSync\pCompareDBSync\py pCompareDBSync.py

-> pCompareDBSync.exe 现在确实包括 py/pCompareNVR.py -> OK

这为我解决了这个问题!

我遇到了与 OP 相同的问题(由于这在 google 搜索中经常出现,所以我会补充我的经验)。

类似的文件夹布局,在同一位置保存包含 mycommon.pycommon 文件夹。作为 CI 构建步骤的一部分,我是来自 myMainDir 的 运行 PyInstaller。

我已经尝试了建议的解决方案:设置 --paths、在 spec 文件中声明隐藏的导入等。我仍然无法让它工作。

我通过在构建脚本中添加一个步骤将 common 文件夹复制到 myMainDir 在 运行 PyInstaller 之前解决了这个问题。