如果你也被pyinstaller折磨,建议阅读,pyinstaller打包教程。

最近打算把自己写的程序用pyinstaller做一个打包,以便在其他电脑上使用,本来以为挺简单的事情,没想到搞了两天时间才搞定,期间遇到诸多坑,忍不住要骂娘了。

平心而论,搞不定只能是自己学艺不精,所以只能调整好心情,挨个去排除异常,面向csdn编程。

提醒:

如果你打包的程序是单文件,并且不依赖于第三方库、第三方软件,那就没必要看本文。网上大把的教程,一行命令就成功打包了。

如果你的项目文件写的比较正规、多目录、并且还依赖了第三方的软件或文件等等,那本篇文章是比较有参考价值的。

如果你也被pyinstaller折磨,建议阅读,pyinstaller打包教程。_第1张图片

 我的项目目录如上图。


ok,进入正题。

需要说明的是,每个人的python解释器版本不同,甚至用到的pyinstaller版本不同,都会产生各种问题。

总体思路:

项目完毕后,在自己的pycharm里先运行,看是否报错,报什么错。将报错信息复制到别的文档中去,方便挨个排查。

报错信息通常都包含关键词:error、warning。

所以,你只需要在你刚才粘贴过去的文档 ctrl+f,然后查找错误信息即可。

第一部分:pyinstaller常见错误应对方案

常见错误1:UPX is not available

有英文基础的话,就很清楚的知道,它说的是upx不可用。

因为pyinstaller打包会用到压缩功能,而这个功能依赖于UPX,UPX是一款压缩软件,所以,你应该下载UPX的安装包,然后把upx.exe文件放在项目虚拟环境中的Scripts文件夹下。

具体操作方法看这篇参考文章:

pyinstaller打包时提示UPX is not available._Veiko的博客-CSDN博客

常见错误2:致命问题、pyinstaller版本问题导致出现以下问题:

第一种:TypeError: an integer is required

第二种:win32*******.error 。比如文件找不到,外部卷被破坏之类各种win32错误

如果你遇到这两种错误,先卸载你的pyinstaller。重新用下面的命令安装

pip install https://github.com/pyinstaller/pyinstaller/archive/develop.tar.gz

我使用这个办法,成功解决了上面两种错误。

参考文章:

python用pyinstaller生成exe时报错 TypeError: an integer is required (got type bytes)_TLScott的博客-CSDN博客


ok,上面是常见错误,一般刚开始用pyinstaller都很容易遇到,下面再说一些我遇到的其他错误

错误三:pyinstaller打包moviepy时各种报错

凡是你用到moviepy库,总是会遇到各种奇葩报错。

背后真正的原因是,我们使用的第三方库在运行时,也会导入其他第三方的库。专业名词叫隐藏导入。

大多数模块的开发者都会根据python版本的变化,及时更新正确的语法和用法。

但是moviepy的开发者就偷懒了,使用了一种偷懒的方法去导入第三方库。

所以,我们在用的时候,会报各种乱七八糟的错。

解决办法是,修改下面两个文件的内容。

如果你也被pyinstaller折磨,建议阅读,pyinstaller打包教程。_第2张图片

 注意,是all文件夹下面的--init--.py,别修改错了

打开后页面如下:

如果你也被pyinstaller折磨,建议阅读,pyinstaller打包教程。_第3张图片

 如果你也被pyinstaller折磨,建议阅读,pyinstaller打包教程。_第4张图片

 我们这里修改的是moviepy.audio.fx.all.__init__.py, 另外一个moviepy.video.fx.all.__init__.py也做同样操作。

注意,不要修改错了,是all文件夹下面的__init__,不是它的同级目录的init。

另外:网上别人给出的代码不要直接复制过去,一定要像我上面演示的一样,手动打印结果,再复制修改。

因为每个人的moviepy版本可能都不一样,你复制别人的代码,到时候还是可能会报错!

参考文章:

​​​​​​moviepy应用pyinstaller打包后执行报错AttributeError: module audio/video.fx.all has no attribute fadein、crop_LaoYuanPython的博客-CSDN博客c


错误四:pyinstaller打包后运行报错,路径找不到。

自己在pycharm里运行,完全没问题,直接在打包后的目录里运行也没问题。

换个目录运行或者换个电脑,就报错。

老手一看,哎,这不就是相对路径没用好么,把项目里的绝对路径改为相对路径。这样换目录、换电脑运行不就可以了?

思路完全正确,不过可能依旧解决不了问题!

如果你也被pyinstaller折磨,建议阅读,pyinstaller打包教程。_第5张图片

我就遇到了,死活搞不定,明明打包后的文件夹里就有配置文件,就是获取不到文件路径。

最后使用了‘冻结路径’的方法配置资源文件路径,程序成功运行。

简单的说,就是在自己项目的根目录中再创建一个py文件,里面定义两个函数,来做一些判断。

这样,程序会根据不同的运行回来,来取不同的值

如果你也被pyinstaller折磨,建议阅读,pyinstaller打包教程。_第6张图片

 自己的哪个模块需要使用资源文件,就在对应的py文件中导入这个自定义的模块frozen.py,然后来获取路径的值。

表达的有点绕口,截图展示一下。

如果你也被pyinstaller折磨,建议阅读,pyinstaller打包教程。_第7张图片

 比如我的业务代码都在src文件中,需要用到这些资源文件的地方,就用上面我们自定义的模块的函数来取值即可。

至此:程序已经成功运行,在别的电脑也没问题。

参考文章:Python项目打包后找不到路径问题,将资源文件数据文件打包到exe文件中_马克图布s的博客-CSDN博客_python打包路径问题

二:spec文件配置文件简介

打包多文件夹、并且还要依赖其他的一些字体文件、音视频文件、甚至第三方软件、亦或者一些dl文件,都需要在spec里配置。

配置好了之后直接 pyinstaller xxx.spec即可。

这是必须要学会的技巧。

spec文件可以使用命令 pyi-makespec xxx.py 即可生成,其中xxx是你的项目入口文件

如果你也被pyinstaller折磨,建议阅读,pyinstaller打包教程。_第8张图片

 生成之后,我们主要需要配置的就是这4个地方,其他的无伤大雅。

咱主要说一下这个datas参数

可以看到datas是一个列表,列表的元素只能是元组,元组第一个元素是你想要打包的文件或者文件夹路径,右边是打包后的程序目录路径。

  1. 如果需要打包一整个文件夹下面的所有内容,需要写入(‘filename’,'filename')
  2. 如果只需要打包某一文件夹写的某一文件,写入格式(‘filedir/filename’,‘‘filedir/filename’’)
  3. 如果想打包某一文件到程序的根目录,写入格式(‘filename’,‘.’),左边是文件,右边写一个点就可以了。
  4. 项目运行中的py文件,不需我们手动配置,自己会打包的。
  5. 非py文件所在的文件夹,如果不手动配置,则不会打包。比如我的项目目录下有虚拟文件的目录venu,如果不添加到datas列表中,则不会被打包。一般情况下也无需打包,特殊情况可能需要打包。


这些配置完毕之后,运行pyinstaller xxx.spec即可,打包后的程序在dist目录下。


还有一个问题:

使用.cfg文件配置文件路径有一个坑,这里说明一下。

如果你也被pyinstaller折磨,建议阅读,pyinstaller打包教程。_第9张图片

 cfg文件里的路径,不要加引号,直接写上去就可以了。

如果加了引号,会导致configparser模块获取到的路径和你配置的不同,会引起一些不必要的错误。

比如,我就遇到了,很抓狂....

如果你也被pyinstaller折磨,建议阅读,pyinstaller打包教程。_第10张图片

 抓耳挠腮半小时,灵光一闪,是不是配置文件的路径不需要引号呢,修改一下就正常了.....


你可能感兴趣的:(pycharm,python,经验分享)