简体   繁体   English

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

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

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 mycommon module. MyMain.exe已创建,但在运行时,告知无法找到mycommon模块。

PyInstaller 's official manual describes this issue: PyInstaller的官方手册描述了这个问题:

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. 某些Python脚本以PyInstaller无法检测的方式导入模块:例如,通过将__import__()函数与变量数据一起使用,或者在运行时操作sys.path值。 If your script requires files that PyInstaller does not know about, you must help it. 如果您的脚本需要PyInstaller不知道的文件,您必须提供帮助。

It also suggests what 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 . 如果Analysis认识到需要一个模块,但找不到该模块,那通常是因为脚本正在操作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: 在这种情况下最简单的方法是使用--paths=选项列出脚本可能搜索导入的所有其他位置:

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

These paths will be added to the current sys.path during analysis. 在分析期间,这些路径将添加到当前sys.path中。

Therefore, please specify the --paths argument while building the application. 因此,请在构建应用程序时指定--paths参数。 The manual states that specifying the -p argument is equivalent: 手册指出指定-p参数是等效的:

-p dir_list , --paths=dir_list -p dir_list , - --paths=dir_list

Set the search path(s) for imported modules (like using PYTHONPATH ). 设置导入模块的搜索路径(如使用PYTHONPATH )。 Use this option to help PyInstaller to search in the right places when your code modifies sys.path for imports. 当您的代码修改sys.path以进行导入时,使用此选项可帮助PyInstaller在正确的位置进行搜索。 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. (在Windows下)或:所有其他平台),或多次提供选项以提供多个搜索路径。

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. Yoel的答案对我来说是正确的,但我需要在Windows中仔细设置路径。 Here is what I did: 这是我做的:

My main py is: 我的主要信息是:

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 - >确定

And that solved this issue for me! 这为我解决了这个问题!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM