利用Pyinstaller打包一个完整的python项目及注意事项

前言

这是一个关于如何利用pyinstaller去打包一个完整的项目(其中包括环境依赖和exe可执行文件)的主要过程。
通过pyinstaller打包好后,在其他电脑中运行.exe可执行程序时不需要配置相关环境依赖即可顺利运行。
此外,还分享了在打包过程和打包完成后以及在其他电脑上运行等出现的一些问题的解决方法。

有关pyinstaller

  • 安装pyinstaller --> pip install pyinstaller
  • 主要的命令选项
–h,–help 模块的帮助信息
-F 产生单个可执行文件
-D 产生一个目录(包含多个文件)作为可执行文件
-w exe程序运行时是否显示命令符窗口
–hidden-import module-name 隐藏不需要的导入模块

多隐藏方法 --hidden-import 'xxx,xxx,xxx'
详细的pyinstaller命令介绍

正式开始

对于打包一个完整项目,首先需要一个干净的环境(包括新建的conda环境或没有安装第三方库的全局python系统环境)。
为了避免打包时出现一些不必要的错误,这里推荐没有安装第三方库的全局python系统环境。(仅为推荐,新建一个conda环境也行).
另外,请确保路径中不包含中文等特殊字符。

  • 打包的基本指令为 pyinstaller -option xxx.py

基本流程:

  • 1.同时按 win + R 键,输入cmd来调出命令符提示符,通过pip安装需要的第三方库(这里推荐在pycharm中进行,pycharm会提示安装所需要的第三库)

  • 2.之后再调出命令提示符,按以下例子来输入(例如项目文件夹路径是E:\test) --> C:\Users\user-name>E:–> E:\>cd test(这里推荐在文件资源管理器中进入到项目的文件夹中,在路径输入栏中输入cmd直接进入)

  • 3.然后先用pyinstaller窗口模式进行调试(打包大环境推荐用 -D,例如主要的py文件为test.py) --> pyinstaller -D test.py

  • 4.之后再回顾打包过程中出现的一些问题,修复后在运行行dist\项目名\文件夹中的.exe文件

  • 5.将运行时出现的问题解决后,删除项目文件夹中的(_pycache_,build,dist,xxx.spec)文件

  • 6.再通过以下命令隐藏命令符窗口打包项目 pyinstaller -D -w xxx.py

  • 7.最后将dist文件夹下的文件夹压缩成压缩包后迁移到别的电脑中运行。

出现的一些问题

. 提示打包好后,回顾打包过程中出现的一些问题


问题一.No module name “xxx”

这是缺少第三方库,看见这个就可以直接用pip安装这个库

问题二.Hidden import not found “xxx”

这个大多数不会影响程序的运行,可以忽略

问题三.有提示WARNING

只要程序能正常运行,这个警告可以忽略

.打包好后,运行程序出现的一些问题


问题四.Failed to execute script [.exe文件名]

一般是由于scikit-image这个库导致的。由于所使用的设备缺少某些.dll文件或缺少某些第三方库的依赖文件。如,缺少了C++运行库,可下载vc_redistx64.exe

问题五.闪退

主要是因为一些库没有安装到或者打包时pyinstaller强行打包了一些不必要的库。
解决方法:这个问题主要在基本流程的第5步中常出现。要是按照基本流程来做,只需要打开.exe文件,通过查看命令符窗口报的错来解决(通常窗口消失快,可通过windows截屏快捷键__win + Shift + S__来截取报错内容))。或者,以有窗口模式下打包项目,之后将.exe文件托入命令符窗口中来查看错误。(再或者,用手机录制运行时的整个过程)
例如提示no module name “xxx”,先检查是否是需要的库,若是不必要的库可通过以下命令重新打包(例如库名字为scipy.xxx.xxx) pyinstaller -D test.py --hidden-import scipy.xxx.xxx

问题六.深度学习的多线程

主要情况为,使用含有深度学习模型进行预测的.exe可执行程序时,同时出现多窗口(例如有包含qt时会打开多个窗口)。解决方法:新建一个py文件命名为multiprocessing_win.py,写入以下代码。

import sys  
import multiprocessing  
  

try:  
    
    if sys.platform.startswith('win'):  
        import multiprocessing.popen_spawn_win32 as forking  
    else:  
        import multiprocessing.popen_fork as forking  
except ImportError:  
    import multiprocessing.forking as forking  
  
if sys.platform.startswith('win'):  
    
    class _Popen(forking.Popen):  
        def __init__(self, *args, **kw):  
            if hasattr(sys, 'frozen'):  
                
                
                os.putenv('_MEIPASS2', sys._MEIPASS)  
            try:  
                super(_Popen, self).__init__(*args, **kw)  
            finally:  
                if hasattr(sys, 'frozen'):  
                    
                    
                    
                    
                    if hasattr(os, 'unsetenv'):  
                        os.unsetenv('_MEIPASS2')  
                    else:  
                        os.putenv('_MEIPASS2', '')  
  
    
    forking.Popen = _Popen   

之后将这个文件放到项目的根目录中,并在执行多进程的py文件中写入

import multiprocessing_win
import multiprocessing

按以上要求做好后,在实现图形界面的py文件中或主py文件中按以下例子加入

import multiprocessing_win
import multiprocessing

if __name__ == '__main__':
    multiprocessing.freeze_support()
    app.run() 
    

.迁移到其他电脑中,运行时出现的一些问题。


问题七.Failed to execute script pyi_rth__tkinter

在pythonxx/lib目录下,找到pyinstaller/hooks/hook-tkinter.py
通过搜索找到path_to_tcl,再按以下例子修改(主要为添加了and ‘Python’ not in path_to_tcl来防止路径丢失报错)

path_to_tcl = bins[0][1]
#if 'Library/Frameworks' in path_to_tcl:
if 'Library/Frameworks' in path_to_tcl and 'Python' not in path_to_tcl:

问题八.Failed to execute script pyi_rth_certifi

主要为python的ssl证书过期的原因。
解决方法主要有:

  • 1.安装OpenSSL库
  • 2.缺少了ssl证书,因此可以从Python官网上下载相应python版本的压缩包,解压后将解压包中的_ssl.pyd(复制到Anaconda目录下DLLs下覆盖原文件),将libcrypto-1_1.dll、libssl-1_1.dll(复制到Anaconda或python根目录)。
  • 3.把import requests或者类似import了爬虫库的地方直接注释掉或者删掉(需要利用网络的可忽略)

我的Github地址:https://github.com/ReverseSacle

你可能感兴趣的:(python)