Python 官方文档:入门教程 => 点击学习
文件打包 概要 脚本打包exe:win/Mac【终端】Qt5,开发桌面应用打包qt5程序【桌面应用】 1.exe 打包 pip install pyinstaller 注意事项: 支持mac、win(windows建议使用py
pip install pyinstaller
注意事项:
配合虚拟环境打包
Mac系统下:1、在mac系统上先开发(为这个程序创建一个虚拟环境) dream2、开发........(安装各自用到的包)3、开发完毕后pip freeze > reqirements.txt(将不同的包写入到程序中)4、打开Windows虚拟机(专门对程序进行打包)5、创建一个虚拟环境(专门用来写项目用的)6、安装项目依赖 pip install -r reqirements.txt7、安装pyinstallerpyinstaller -F xxxxx产出:dream.exe
Windows系统下:1、创建虚拟环境+项目 dream2、开发 开发完毕后 pip freeze > reqirements.txt(将不同的包写入到程序中)(可有可无)3、安装pyinstallerpyinstaller -F xxxxx产出: dream.exe#可以不用写pip freeze > reqirements.txt(这步)#原因:利用自己的Windows系统已经存在这个环境文件了。
过程详解:
pyinstaller -D 项目名pyinstaller -D app.py
文件解读
build:中间编译过程中产出的代码(基本没用)
dist:打完包后的结果。可以运行的文件(将app文件夹压缩打给其他人解压----->点击app.exe即可运行程序)
app.spec:打包过程中生成的配置文件。
在写代码过程中可能会写错代码导致错误,如果是正常的点击exe文件运行程序,则会进入,运行到错误的时候后马上闪退,并且无法知道报错的类型及原因!
解决办法:
明显细节可能出错:输入文本类型会报错
text = int(input("请输入信息:"))
重新打包程序(将之前打包产生的文件都删除,即build文件夹、dist文件夹、app.spec)
打包完成后按照上述方法
pyinstaller -F 项目名pyinstaller -F app.py
可以很明显的看到打包后的dist文件夹内只有app.exe一个文件(即可执行exe程序文件)
运行效果如刚才所示
pyinstaller -F 项目名 -n 文件名pyinstaller -F app.py -n 哔哩哔哩pyinstaller -D 项目名 -n 文件名pyinstaller -D app.py -n 哔哩哔哩
[-h] [-v] [-D] [-F] [--specpath DIR] [-n NAME] [--add-data ] [--no-embed-manifest] [-r RESOURCE] [--uac-admin] [--uac-uiaccess][--win-private-assemblies] [--win-no-prefer-redirects] [--argv-emulation][--osx-bundle-identifier BUNDLE_IDENTIFIER] [--target-architecture ARCH][--codesign-identity IDENTITY] [--osx-entitlements-file FILENAME] [--runtime-tmpdir PATH] [--bootloader-ignore-signals] [--distpath DIR] [--workpath WORKPATH] [-y][--upx-dir UPX_DIR] [-a] [--clean] [--log-level LEVEL]scriptname [scriptname ...]
参数 | 说明 |
---|---|
-F | 产生单个的可执行文件 |
-D | 产生一个目录(包含多个文件)作为可执行程序 |
-a | 不包含 Unicode 字符集支持 |
-d | debug 版本的可执行文件 |
-w | 指定程序运行时不显示命令行窗口(仅对 Windows 有效) |
-c | 指定使用命令行窗口运行程序(仅对 Windows 有效) |
-o | 指定 spec 文件的生成目录。如果没有指定,则默认使用当前目录来生成 spec 文件 |
-p | 设置 Python 导入模块的路径(和设置 PYTHONPATH 环境变量的作用相似)。也可使用路径分隔符(Windows 使用分号,linux 使用冒号)来分隔多个路径 |
-n | 指定项目(产生的 spec)名字。如果省略该选项,那么第一个脚本的主文件名将作为 spec 的名字 |
下载icon(图标文件)
也可以将图片转化为icon(图标文件)
用以下命令自定义exe图标
pyinstaller -F -i icon文件名 程序名pyinstaller -F -i bit.ico app.py
很明显可以看到我们的程序图标已经发生变化
import osp1 = os.path.abspath(__file__) #os模块读取当前文件所在绝对目录print(p1)# E:\Luffycity\exe\bilibili\app.pyp1 = os.path.dirname(os.path.abspath(__file__)) # os模块读取当前文件所在绝对目录的上一级目录print(p1) #E:\Luffycity\exe\bilibili
import os#声明根目录BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # os模块读取当前运行文件所在绝对路径的上一级目录print("------欢迎使用dream系统!------")#os.path.join(BASE_DIR,"acount.txt") : 拼接路径 即 把txt文件路径拼接到BASE_DIR路径下面with open(os.path.join(BASE_DIR,"acount.txt"), mode='r', encoding='utf8') as f: data = f.read().strip()
为什么会报错?#只生成了一个dist文件//多文件打包:在运行程序exe文件时,是会解压所有的文件的,多文件打包时可以读取到每个文件夹的路径及内容//单文件打包:在运行exe程序时,会解压所有的文件到虚拟文件目录,无法读取到写死的文件夹目录
创建demo.py文件,将sys.argv函数写进去。
import sys#sys.argv : 列表内存储的是列表(列表内存的就是当前程序所在的目录)print(sys.argv) # ['E:\\Luffycity\\exe\\bilibili\\demo.py']print(sys.argv[0]) # E:\Luffycity\exe\bilibili\demo.py
将demo.py封装成exe程序
pyinstaller -F demo.py
在命令行终端运行即可看到文件路径
在exe程序代表可执行程序的文件所在路径
['E:\\Luffycity\\exe\\bilibili\\demo.py']
找到文件所在的绝对路径
#os.path.relpath : 找到所在文件的绝对路径BASE_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
修改BASE_DIR的路径
import timeimport osimport sys# 声明根目录# BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # os模块读取当前运行文件所在绝对路径的上一级目录#拿到程序所在的根目录BASE_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))print("------欢迎使用dream系统!------")# os.path.join(BASE_DIR,"acount.txt") : 拼接路径 即 把txt文件路径拼接到BASE_DIR路径下面with open(os.path.join(BASE_DIR, "acount.txt"), mode='r', encoding='utf8') as f: data = f.read().strip()print(data)time.sleep(5)
重新打包exe文件
pyinstaller -F app.py -n 哔哩哔哩
注意将想要读取的文件copy到程序所在目录,否则会报错
运行效果 -- 正常读取文件内容
import sysif getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): print('running in a PyInstaller bundle')else: print('running in a nORMal Python process')
条件选择
如果是程序运行文件
如果是py文件
if getattr(sys, 'frozen', False): #executable : 当前执行文件的文件目录 BASE_DIR = os.path.dirname(sys.executable)else: #文件夹所在目录 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
app.py文件
import timeimport osimport sysif getattr(sys, 'frozen', False): #executable : 当前执行文件的文件目录 BASE_DIR = os.path.dirname(sys.executable)else: #文件夹所在目录 BASE_DIR = os.path.dirname(os.path.abspath(__file__))print("------欢迎使用dream系统!------")# os.path.join(BASE_DIR,"acount.txt") : 拼接路径 即 把txt文件路径拼接到BASE_DIR路径下面with open(os.path.join(BASE_DIR, "acount.txt"), mode='r', encoding='utf8') as f: data = f.read().strip()print(data)time.sleep(5)
定义两个函数文件 db.py和encrypt.py
db.py
def get_data_base(): return "Mysql"
encrypt.py
def md5(): return "加密"
在主文件(app.py)中导入这个包并调用这两个函数
打包exe:会发现这两个函数(包)默认帮我打到我依赖的包里面
定义三个函数文件 db.py、encrypt.py、tree.py
db.py
from . import treedef get_data_base(): print(tree.get_name()) return "mysql"
encrypt.py
def md5(): return "加密"
tree.py
def tree(): return tree
重新打包运行exe程序
正常运行且可以看到从另一个依赖的包导入的函数
当写的内容较少时,导入的模块会默认被添加到默认依赖里面
import timeprint("------欢迎使用dream系统!------")# #正常常规写法from utils import cardcard.get_number()time.sleep(5)
import importlib #动态模块导入依赖包
import timeprint("------欢迎使用dream系统!------")#借助模块动态导入方法import importlibcard = importlib.import_module('utils.card')v1 = card.get_number()print(v1)time.sleep(5)
问题:
虽然动态模块导入可以 运行 import importlib 将此依赖包加入到默认依赖中
但是无法 通过 card = importlib.import_module('utils.card') 这行代码,将其中的card函数(包)加入到默认依赖中
程序名.spec(哔哩哔哩.spec):pyinstaller打包时读的配置文件
在 hiddenimports 手动加入需要动态导入的包
hiddenimports=[ "utils.card", ],
注意:再次重新打包时
不能使用
pyinstaller -F app.py -n 哔哩哔哩
应该使用
pyinstaller -F 哔哩哔哩.speC#此语句可能会报这个错#makespec options not valid when a .spec file is given#解决办法:不加 -Fpyinstaller 哔哩哔哩.spec
来源地址:https://blog.csdn.net/Chimengmeng/article/details/129610194
--结束END--
本文标题: Python文件打包exe程序
本文链接: https://www.lsjlt.com/news/433834.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0