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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32093559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 10:59:02  来源:igfitidea点击:

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

pythonpython-2.7python-3.xpython-2.6pyinstaller

提问by DarkMagic

I create two python files, and the directory/file relations is as follows:

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

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

In mycommon.py:

在 mycommon.py 中:

def myFunc(a):
    ...

And in myMain.py:

在 myMain.py 中:

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

Then I created exe using pyinstaller:

然后我使用pyinstaller创建了exe:

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

MyMain.exe is created, but when run, is tells that can not find mycommonmodule.

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

采纳答案by Yoel

PyInstaller's official manual describesthis issue:

PyInstaller的官方手册描述了这个问题:

Some Pythonscripts import modules in ways that PyInstallercannot detect: for example, by using the __import__()function with variable data, or manipulating the sys.pathvalue at run time. If your script requires files that PyInstallerdoes not know about, you must help it.

某些Python脚本以PyInstaller无法检测到的方式导入模块:例如,通过使用__import__()具有可变数据的函数,或sys.path在运行时操作值。如果您的脚本需要PyInstaller不知道的文件,您必须帮助它。

It also suggestswhat should be done in such a case:

它还建议在这种情况下应该做什么:

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

These paths will be added to the current sys.pathduring analysis.

如果 Analysis 识别出需要某个模块,但找不到该模块,通常是因为脚本正在操纵sys.path. 在这种情况下,最简单的做法是使用该--paths=选项列出脚本可能正在搜索导入的所有其他位置:

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

这些路径将sys.path在分析过程中添加到电流中。

Therefore, please specify the --pathsargument while building the application. The manual statesthat specifying the -pargument is equivalent:

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

-p dir_list, --paths=dir_list

Set the search path(s) for imported modules (like using PYTHONPATH). Use this option to help PyInstallerto search in the right places when your code modifies sys.pathfor 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.

-p dir_list, --paths=dir_list

设置导入模块的搜索路径(如使用PYTHONPATH)。使用此选项可帮助PyInstaller在您的代码修改sys.path导入时在正确的位置进行搜索。提供一个或多个由;(在Windows下)或:(所有其他平台)分隔的路径,或多次提供选项以提供多个搜索路径。

回答by Al-Noor Ladhani

Also I had to fight a bit to get pyinstaller correctly import python scripts in a subfolder where the path to the subfolder was set relatively via sys.path.insert.

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

The answer by Yoel was correct for me but I needed careful setting of paths in Windows. Here is what I did:

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

My main py is:

我的主要 py 是:

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

My imported py is:

我导入的py是:

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

(I have many of such imported py's in folder .\py\ but here i just use a single one as example)

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

So my main PY, I have the following include:

所以我的主要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 that did NOT include py/pCompareNVR.py

-> 不包含 py/pCompareNVR.py 的 pCompareDBSync.exe

I had to include the absolute pad to the main PY and the imported PY's:

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

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

-> pCompareDBSync.exe that did now include py/pCompareNVR.py -> OK

-> pCompareDBSync.exe 现在包含 py/pCompareNVR.py -> OK

And that solved this issue for me!

这为我解决了这个问题!