Python中如何用pyinstaller打包包含预加载dat文件的源文件?
大侠们,你们好,小弟请教一个问题
1:请问如何用 pyinstaller 打包 python 源文件里有打开和加载某个预定的 dat 文件?
2:还有就是 pyinstaller 打包的文件基本超过 5M 了。请问有什么办法或者什么模块把生成的文件变小一些吗?
Python中如何用pyinstaller打包包含预加载dat文件的源文件?
- 有参数可以指定打包额外的目录作为资源文件,
2. 没办法,因为 python 本身的体积在那摆着呢。可以尝试启用 upx
问题核心: 在打包时,PyInstaller默认不会自动包含非.py的静态数据文件(如.dat文件)。你需要通过修改.spec文件或使用命令行参数明确告诉它哪些文件需要被打包进去。
解决方案: 最可靠的方法是使用PyInstaller的--add-data参数。这个参数的作用是把项目文件夹里的数据文件,复制到打包后程序的相对目录里。
具体操作: 假设你的项目结构如下:
你的项目/
├── main.py # 你的主程序
└── config.dat # 你的数据文件
你想在打包后,config.dat文件能放在和可执行文件相同的目录下(或者在一个子目录里,比如data/),供程序读取。
1. 使用命令行直接打包(推荐用于简单项目): 打开终端(命令行),进入你的项目目录,然后运行:
pyinstaller --onefile --add-data "config.dat:." main.py
--onefile: 打包成单个exe文件。--add-data "源路径:目标路径": 这是关键。"config.dat:."表示“把当前目录下的config.dat文件,复制到打包后程序的根目录(用.表示)”。- 如果你的文件在子目录里,比如
data/config.dat,并且你想把它放到exe同级的data文件夹里,就写成:--add-data "data/config.dat:data"。
2. 通过修改.spec文件打包(适用于复杂项目):
首次运行pyinstaller main.py会生成一个main.spec文件。编辑这个文件,找到datas=[]这一行,修改它:
# 在 spec 文件中
a = Analysis(
['main.py'],
pathex=[],
binaries=[],
datas=[('config.dat', '.')], # 这里!添加这行
hiddenimports=[],
hookspath=[],
...
)
括号里('config.dat', '.')的含义和命令行参数一样:源文件 -> 目标目录。修改后保存,然后运行pyinstaller main.spec重新打包。
3. 在代码中如何正确读取这个文件(关键一步!):
打包后,程序运行时的当前目录可能不是exe所在目录。为了无论以源码运行还是打包后运行都能找到文件,你需要使用PyInstaller提供的运行时变量sys._MEIPASS。
在你的main.py中,使用以下代码来获取数据文件的正确路径:
import sys
import os
def get_resource_path(relative_path):
""" 获取资源的绝对路径。供打包后PyInstaller使用。"""
if hasattr(sys, '_MEIPASS'):
# 如果是打包后的程序,sys._MEIPASS是临时解压目录
base_path = sys._MEIPASS
else:
# 如果是直接运行源码,就用当前文件所在目录
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
# 使用示例
dat_file_path = get_resource_path('config.dat') # 如果文件在根目录
# 或者 dat_file_path = get_resource_path('data/config.dat') # 如果文件在data子目录
with open(dat_file_path, 'r') as f:
content = f.read()
# ... 处理你的数据
这段代码是通用写法,它会自动判断运行环境,从而指向正确的文件位置。
总结建议: 记住--add-data和sys._MEIPASS这个组合拳,就能搞定PyInstaller打包数据文件的问题。
多年前,我也曾尝试打包 Python 的程序为一个 exe
最后,我放弃了
还是用合适的工具做合适的事吧
楼上说的对,我转 PS 了
我一般偷懒就直接把要加载的文件用相对路径,然后打包的时候加-F 选项生成一个 exe,那些文件就放 exe 同目录下,或者 exe 同目录建个 res 目录把资源文件全放进去。。5m 很大么,,我一般都用 pyqt 写小工具,mac/win 的包一般 15m+,linux 包更是将近 50m 了都
https://github.com/debuggerx01/JSONFormat4Flutter/releases
加-F 的话程序启动速度会变慢很多。而且我遇到过加-F 打包数据文件调用失败的。
编辑. spec 文档去控制打包时包含的数据文件,参考:
https://blog.csdn.net/u010159842/article/details/53212443
感谢楼上的回复,真心感谢。

