PyInstaller打包python程序为exe可执行文件

教程千千万,貌似我的window电脑就是打包不了,而且不同电脑的表现都不一致,很是奇怪。


文章目录

  • 1 极简版
    • 1.1 生成文件`spec`详解
    • 1.2 是否变成一个exe主文件
  • 2 虚拟环境打包
  • 3 其他打包需求
    • 3.1 加密打包
    • 3.2 Pyinstaller打包多个py文件为一个exe文件
  • 4 如何反编译
  • 5 一些报错
    • 5.1 utf-8' codec can't decode byte 0xce in position
    • 5.2 exe文件要从dist文件拿出来
    • 5.3 windows打包会将所有之前的依赖统统整上
    • 5.4 pyinstaller的版本一定要保证最新
    • 5.5 A RecursionError (maximum recursion depth exceeded) occurred
    • 5.6 模块找不到的问题解决办法


官方地址:
https://github.com/pyinstaller/pyinstaller
官方文档:https://pyinstaller.org/en/stable/

python版本要求: Python version 3.8-3.12.

1 极简版


pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyinstaller #清华源

然后


Pyinstaller -F py_word.py 打包exe
Pyinstaller -F -w py_word.py 不带控制台的打包
Pyinstaller -F -w -i chengzi.ico py_word.py 打包指定exe图标打包

这里的参数设定:
在这里插入图片描述

来看看生成的文件都是什么:

  • 同名的.spec:重要配置文件,.spec文件中主要包含4部分:Analysis、PYZ、EXE、COLLECT:
    • Analysis:主要是分析py文件的依赖信息
    • PYZ:是一个.pyz的压缩包,包含程序运行需要的依赖
    • EXE:是根据上述两项内容而生成的
    • COLLECT:主要是输出信息
  • dist文件夹:最终的exe文件存放位置,可能要从dist拿出来
  • build文件夹:中间过程,创建好之后可以直接删除

1.1 生成文件spec详解

参考:
https://blog.csdn.net/kevinshift/article/details/104880101

其实如果你自己会写.spec,可以直接通过pyinstaller xx.spec来执行打包

# -*- mode: python ; coding: utf-8 -*-
a = Analysis(['gui.py'],
             pathex=['D:\\gui'],
             binaries=[],
             datas=[('D:\\gui\\config.ini','.'),('D:\\gui\\清洗规则.xlsx','.')],
             hiddenimports=['pandas'],
             hookspath=[],
             hooksconfig={},
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)

datas里边的元素是以元组的形式来存储的,有这么一个映射关系:

datas = [('源文件路径','目标路径')]

如果有多个,就多放几个元素,内容不限,如果目标路径是打包后的根目录,那就写.
修改好之后,运行这条命令即可:

pyinstaller  xx.spec

其中datas和binaries注意,这是一个键值对,可以枚举一个或多个。
其中,前边的表示拷贝的文件,第二个表示拷贝的路径。

#注意,必须有'.'。否则报错:ValueError: too many values to unpack (expected 2)
#下面这个表示将文件\lib\general.pyc拷贝到当前文件夹下,就是解压的__MIE...等
binaries=[(r'\lib\general.pyc','.')],	

#下面表示将\lib\general.xml拷贝到.\data文件夹下
datas=[(r'\lib\general.xml',r'.\data')],

#还可以整个文件夹的拷贝,或者一类文件的拷贝。如下设置了多个规则的
datas= [ ('/mygame/sfx/*.mp3', 'sfx' ) ,	#/mygame/sfx/文件夹下所有mp3
		( '/mygame/data', 'data' ),			#/mygame/data文件夹下所有文件
		( 'src/README.txt', '.' ),
		],

上面说了有时候我们需要另外添加资源文件,可以通过编辑spec文件,也可以通过命令行参数。

例如使用opencv的时候存在找不到视频编解码器的情况(Pyinstaller详细教程)
即找不到opencv_ffmpeg341_64.dll
这时候需要我们手动设置资源路径,

可以通过–add-binary参数设置,也可以在spec文件添加binaries参数,这个参数是个list,每个元素是个二元组

binaries=[('D:\\ProgramSourceCode\\PycharmProjects\\video_proc\\venv\\Lib\\site-packages\\cv2\\opencv_ffmpeg341_64.dll', './cv2')]

前一个代表原始资源路径,后一个代表拷贝到可执行文件夹的文件路径。

1.2 是否变成一个exe主文件

来自:https://blog.csdn.net/kevinshift/article/details/104880101

# 打包成一个exe文件
Pyinstaller -F py_word.py 打包exe
# 打包成一个文件夹
Pyinstaller py_word.py 打包exe

pyinstaller打包文件包含两种情况:
(1)将py文件、python及第三方库全部打包为一个单独的Exe中。

(2)将以上三者打包形成一个文件夹,文件夹中包含一个Exe,一个python,及其依赖的第三方库。
二者通过不同的选项
二者的优劣对比:
(a)启动时间
单一可执行文件比文件夹的启动时间要长
因为当程序运行时,单一的可执行文件需要解压程序的第三方依赖文件到临时文件夹中。
(b)文件结构
单一可执行文件的文件结构和工程目录是一样的,但是生成文件夹就不一样了,若程序中包含相对路径,这个相对路径自然基于的是文件夹目录,这点需要注意。
在打包过程出现问题时,可以生成文件结构,进入细致查看发生了什么。

2 虚拟环境打包

按照极简版,其可能会将你所有依赖打包,就会让文件变得非常大。
可以使用conda的虚拟环境

#创建虚拟环境
conda create -n aotu python=3.6
 
#激活虚拟环境
conda activate aotu

# 安装必要的依赖
 
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple python-docx
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyinstaller

#Pyinstaller打包
Pyinstaller -F -w -i apple.ico py_word.py

安装完之后,可以在自己的虚拟镜像里面python x.py试一下是否可以正常执行,就可以开始Pyinstaller 打包


3 其他打包需求

3.1 加密打包

加密打包
来自: https://zhuanlan.zhihu.com/p/470301078
虽然被如此轻松的解密手段😰到了,但是Pyinstaller也是支持加密打包的,使用 --key + 密码 参数即可,例如:

pyinstaller --key 666777 xxx.py

不过这个加密也不是很强,对保密性有很强要求的建议使用把需要加密的模块通过C或者C++编写,通过python调用,再打包。

3.2 Pyinstaller打包多个py文件为一个exe文件

来自:https://blog.csdn.net/weixin_43804047/article/details/119704965

建议将所有的非py脚本放在根目录下新建文件夹中去调用,所有的py脚本放在根目录下

project
|---- test.py
|---- func1.py
|---- func2.py
|---- dir
       |------ file
       
# test.py为你要封装的文件,func1.py和func2.py为test.py需要调用的py脚本,dir中的文件为py脚本需要调用的非py类文件

你需要这样运行即可:

$ cd project
$ conda activate your_env
$ pyinstaller -w -D test.py func-1.py func-2.py
# 最新测试
# pyinstaller -w -D test.py 也可以

4 如何反编译

来自: https://zhuanlan.zhihu.com/p/470301078
先下载pyinstxtractor包,提取生成的exe中的pyz(一般是pyc)文件

# 安装:直接执行下载的 py 文件即可
# 解包 xx.exe
python pyinstxtractor.py xx.exe

然后再通过python-uncompyle6工具,将pyc文件反编成.py文件

# 安装 
pip install uncompyle6
# 反编译 xxx.pyc 文件,输出为 xxx.py 源码文件
uncompyle6 -o xxx.py xxx.pyc

5 一些报错

5.1 utf-8’ codec can’t decode byte 0xce in position

来着:https://zhuanlan.zhihu.com/p/470301078

utf-8' codec can't decode byte 0xce in position

这是由于cmd的编码格式导致的。
各种路径错误导致的问题
很多人在拼接路径的时候喜欢使用+来拼接路径字符串,这会导致在打包后出现各种资源无法访问的错误,且不好排查,建议多使用os.path的各种方法来处理路径。

5.2 exe文件要从dist文件拿出来

被调用的脚本需要拷贝到dist中打包好的文件夹中,否则可能导致调用失败

project
|---- test.py
|---- func1.py
|---- func2.py
|---- dir
       |------ file
 input

比如你代码里是直接用./input文件夹,那就要放在跟input平级的文件夹上

5.3 windows打包会将所有之前的依赖统统整上

windows建议使用新建虚拟环境进行打包,新建的envs中只install你的python脚本中import的包即可,这样打包文件很小。笔者做了测试,使用你本来的虚拟环境会把原来的包都打在一块,有300M左右,而新建的envs打包只有50M;Linux系统可以随意安装python库,封装的时候会按照python导入的包去封装,不会将环境内所有package打包。

5.4 pyinstaller的版本一定要保证最新

pyinstaller的版本一定要保证最新,否则运行exe后,小黑框还是原样,什么也不显示,但是拖入cmd中debug是没毛病的。笔者就被这个坑了好久才弄明白。

5.5 A RecursionError (maximum recursion depth exceeded) occurred

Explanation: Python's stack-limit is a safety-belt against endless recursion,
eating up memory. PyInstaller imports modules recursively. If the structure
how modules are imported within your program is awkward, this leads to the
nesting being too deep and hitting Python's stack-limit.

With the default recursion limit (1000), the recursion error occurs at about
115 nested imported, with limit 2000 at about 240, with limit 5000 at about
660.

参考:使用pyinstaller打包pyqt5报With the default recursion limit (1000)

当支行过一次pyinstaller后此时运行过的目录下会有一个与要打包的.py文件同名的.spec文件
打开*.spec文件在文件头添加两行代码:

import sys
sys.setrecursionlimit(2000)

之后通过以下方式继续打包:

pyinstaller -D *.spec

5.6 模块找不到的问题解决办法

参考:使用pyinstaller将python程序打包成exe执行文件时遇到模块找不到的问题

在这里插入图片描述
解决办法是:打包时加入你自编模块(或第三方模块所在文件夹路径),笔者程序中调用了shiyanshi自编模块,在D:\Pycharm\Program路径下。

因此打包时需要添加路径进行打包。

使用pyinstaller ***.py -F -p D:\Pycharm\Program
命令在主程序所在文件目录下进行打包,即可解决模块找不到的问题。

在这里插入图片描述


参考:
Python脚本打包成exe,看这一篇就够了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/189809.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python树长子兄弟链存储结构(孩子兄弟链存储结构)

长子兄弟链存储结构(孩子兄弟链存储结构)解释: 长子兄弟链存储结构是一种树的存储结构,它使用孩子兄弟表示法(也称作左孩子右兄弟表示法)来表示树的结构。这种表示方法主要用于存储一般的树,而不…

【华为OD】B\C卷真题:100%通过:找城市 C/C++实现

【华为OD】B\C卷真题:100%通过:找城市 C/C实现 题目描述: 一张地图上有n个城市,城市和城市之间有且只有一条道路相连:要么直接相连,要么通过其它城市中转相连(可中转一次或多次)。…

智能优化算法应用:基于麻雀算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于麻雀算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于麻雀算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.麻雀算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

Typescript基础面试题 | 01.精选 ts 面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

摄像馆服务预约管理系统会员小程序作用是什么

摄像馆不少人并不会经常去,除了有拍婚纱照或工作照等,一般很少会进店,但由于摄像涵盖多个服务项目,因此总体来讲,市场需求度还是比较高的,一个城市也有多个品牌,而传统门店经营也面临不少痛点。…

stm32 42步进电机 上位机示例

脉冲到底是个啥东西?步进电机一直说发脉冲 步进电机通过接收脉冲信号来实现精确的位置控制。脉冲是一种短暂的电信号,它的变化可以触发步进电机转动一定的角度或步进。步进电机控制系统会根据输入的脉冲信号来精确定位和控制步进电机的转动,每…

Datax安装部署及读取MYSQL写入HDFS

一.DataX简介 1.DataX概述 DataX 是阿里巴巴开源的一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。 源码地址:https://github.com/alibaba/Data…

⑩【Redis Java客户端】:Jedis、SpringDataRedis、StringRedisTemplate

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ Jedis、SpringDataRedis、StringRedisTemplate…

数据结构——线性表

目录 1.线性表的定义 2.顺序表 2.1顺序表的定义 2.2 顺序表的应用 2.2.1 顺序表的管理 (1) 顺序表的初始化 (2) 销毁顺序表 (3) 打印顺序表的值 (4)检查顺序表的容量 &…

C#文件操作File类vsFileInfo类和Directory类vsDirectoryInfo类

目录 一、File类vsFileInfo类 1.File类 (1)示例源码 (2)生成效果 2.FileInfo类 (1)示例源码 (2)生成效果 二、 Directory类vsDirectoryInfo类 1.Directory类 (…

C语言基础介绍

1. C语言基础知识 C语言是一种计算机编程语言,是一门用于编写系统软件和应用软件的高级语言。C语言的基础知识包括: 数据类型:C语言中的数据类型包括整型、浮点型、字符型等。 变量:C语言中使用变量来存储数据,变量必…

量化交易:因子风险暴露

本文介绍了如何计算因子风险暴露的内容。 判断风险暴露的建模是否合理 通常,此分析是基于历史数据,而对历史风险暴露的估计可能会影响未来的风险暴露。 因此,计算因子风险暴露是不够的。 必须对风险暴露保持信心,并明白对风险暴…

Vue框架学习笔记——键盘事件

文章目录 前文提要键盘事件(并不是所有按键都能绑定键盘事件)常用的按键不同的tab和四个按键keyCode绑定键盘事件(不推荐)Vue.config.keyCode.自定义键名 键码 神奇的猜想div标签和click.enterbutton标签和click.enter 前文提要 …

定长子网划分和变长子网划分问题_二叉树解法_通俗易懂_配考研真题

引入:定长子网划分和变长子网划分的基本概念 定长子网划分和变长子网划分的基本概念 目前常用的子网划分,是基于CIDR的子网划分,也就是将给定的CIDR地址块划分为若干个较小的CIDR地址块。 定长子网划分: 使用同一个子网掩码来划分子网,因…

【版本管理 | Git】Git rebase 命令最佳实践!确定不来看看?

🤵‍♂️ 个人主页: AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨‍💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!&…

智能优化算法应用:基于斑点鬣狗算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于斑点鬣狗算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于斑点鬣狗算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.斑点鬣狗算法4.实验参数设定5.算法结果6.参考…

VM虚拟机中Ubuntu14.04安装VM tools后仍不能全屏显示

1、查看Ubuntu所支持的分辨率大小。 在终端处输入: xrandr,回车 2、输入你想设置的分辨率参数。 我设置的为1360x768,大家可以根据自己的具体设备设置。 在终端输入:xrandr -s 1360x768 注意:这里1360后边是字母 x 且…

<JavaEE> Thread线程类 和 Thread的常用方法

目录 一、Thread概述 二、构造方法 三、常用方法 1.1 getId()、getName()、getState()、getPririty() 1.2 start() 1.3 isDaemon()、setDaemon() 1.4 isAlive() 1.5 currentThread() 1.6 Interrupt()、interrupted()、isInterrupted() 1.6.1 方法一:添加共…

S25FL系列FLASH读写的FPGA实现

文章目录 实现思路具体实现子模块实现top模块 测试Something 实现思路 建议读者先对 S25FL-S 系列 FLASH 进行了解,我之前的博文中有详细介绍。 笔者的芯片具体型号为 S25FL256SAGNFI00,存储容量 256Mb,增强高性能 EHPLC,4KB 与 6…

Java中static、final、static final的区别

文章目录 finalstaticstatic final final final可以修饰:属性,方法,类,局部变量(方法中的变量) final修饰的属性的初始化可以在编译期,也可以在运行期,初始化后不能被改变。 final修…