赞
踩
使用 pyinstaller 将 Python 程序打包成可执行文件可以方便分享和跨设备运行。当代码中读取了外部文件时,需要将这些文件一起打包,打包指令应该如何编写?以及打包完成后直接运行程序可能会出现找不到文件的错误,如何解决?
本文将通过一个简单的示例程序,演示需要引入代码以外的文件的场景下打包的整个流程。
假设存在一个简单的python项目,项目结构如下:
example_project/
├── data.txt
├── source_folder/
│ ├── d1.txt
│ └── d2.txt
└── main.py
main.py
代码如下:
if __name__ == '__main__':
data_list = []
with open("data.txt", 'r') as f:
data_list += f.readlines()
with open("source_folder/d1.txt", 'r') as f:
data_list += f.readlines()
with open("source_folder/d2.txt", 'r') as f:
data_list += f.readlines()
print(data_list)
示例的程序很简单,就是分别读取 data.txt
和 source_folder
文件夹下的 d1.txt
、d2.txt
文件,然后把内容合并输出出来。
先安装 pyinstaller 库就不多说了:pip install pyinstaller
正常将程序打包成一个单文件的指令是:pyinstaller -F main.py
但是这样一些非代码文件不会被打包进去,运行的时候就会报错找不到相应的文件。
这时候需要在指令里加入添加外部文件的选项:--add-data=<A>;<B>
这里的 <A>
可以是文件名也可以是文件夹名,表示将该文件或目录下的所有文件都打包进去。;<B>
表示打包后在可执行文件中的相对路径为 <B>
目录,正常和源码中的目录名保持一致,如果是根目录,则用“.
”代替。
因此,本文示例中的打包指令应该改成:
pyinstaller -F main.py --add-data=data.txt;. --add-data=source_folder;source_folder
但是!按照上面的指令打包之后,运行程序还是会提示找不到txt文件,这时候可能很多人都以为是打包指令不对,文件没有打包进去,其实不是,是因为打包完,文件的相对路径变了。系统会在临时存储区创建一个临时目录解压这些打包后的资源。
需要稍微修改下代码,找到系统释放临时文件的路径就可以了。代码如下:
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
之后在加载txt文件的时候,在前面拼接上临时目录路径就可以了:os.path.join(base_path, "xxx.txt")
。
修改后的完整代码如下:
import os
import sys
# 获取打包后可执行文件的路径
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
if __name__ == '__main__':
data_list = []
# 拼接文件路径
with open(os.path.join(base_path, "data.txt"), 'r') as f:
data_list += f.readlines()
# 拼接文件路径
with open(os.path.join(base_path, "source/d1.txt"), 'r') as f:
data_list += f.readlines()
# 拼接文件路径
with open(os.path.join(base_path, "source/d2.txt"), 'r') as f:
data_list += f.readlines()
print(data_list)
代码修改好之后,再用上面的打包指令打包一次,就可以正常运行了。
本文介绍了在使用pyinstaller打包多个外部文件时可能遇到的“找不到文件”的问题,解决方法是在打包指令中加入外部文件的选项,同时对代码加载文件时的路径做出调整。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。