Python中如何用pyinstaller打包包含预加载dat文件的源文件?

大侠们,你们好,小弟请教一个问题
1:请问如何用 pyinstaller 打包 python 源文件里有打开和加载某个预定的 dat 文件?
2:还有就是 pyinstaller 打包的文件基本超过 5M 了。请问有什么办法或者什么模块把生成的文件变小一些吗?
Python中如何用pyinstaller打包包含预加载dat文件的源文件?

7 回复
  1. 有参数可以指定打包额外的目录作为资源文件,
    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-datasys._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

感谢楼上的回复,真心感谢。

回到顶部