Python应用程序打包
PyInstaller将Python应用程序及其所有依赖项捆绑到一个包中。 用户可以运行打包的应用程序,而无需安装 Python 解释器或任何模块。
项目结构:
-
demo
-
data
-
students.json
[ { "name": "花千骨", "sex": "女", "age": 16 }, { "name": "霓漫天", "sex": "女", "age": 18 }, { "name": "轻水", "sex": "女", "age": 17 } ]
-
teachers.json
[ { "name": "白子画", "sex": "男", "age": 100, "course": "语文课" }, { "name": "摩严", "sex": "男", "age": 200, "course": "数学课" }, { "name": "笙箫默", "sex": "男", "age": 50, "course": "英语课" } ]
-
-
student.py
class Student: def __init__(self, name, age, sex): self.name = name self.sex = sex self.age = age def start_learn(self): """开始学习""" print(f'{self.name}开始学习!')
-
teacher.py
class Teacher: def __init__(self, name, age, sex, course): self.name = name self.sex = sex self.age = age self.course = course def start_teach(self): """开始教学""" print(f'{self.name}开始教学!')
-
demo.py
from student import Student from teacher import Teacher def students(): """ 获取学生对象列表 :return: 学生对象列表 """ with open('data/students.json', 'r', encoding='utf-8') as fp: student_list = eval(fp.read()) return [Student(student['name'], student['sex'], student['age']) for student in student_list] def teachers(): """ 获取教师对象列表 :return: 教师对象列表 """ with open('data/teachers.json', 'r', encoding='utf-8') as fp: teacher_list = eval(fp.read()) return [Teacher(teacher['name'], teacher['sex'], teacher['age'], teacher['course']) for teacher in teacher_list] def show(x_list): """展示""" for x in x_list: if isinstance(x, Student): print(x.name, x.sex, x.age) x.start_learn() elif isinstance(x, Teacher): print(x.name, x.sex, x.age, x.course) x.start_teach() def main(): student_list = students() teacher_list = teachers() print("------学生信息------") show(student_list) print("------教师信息------") show(teacher_list) input("请按任意键,再按Enter间结束!") if __name__ == '__main__': main()
-
demo.ico
-
安装PyInstaller
$ pip install -U pyinstaller
Windows
不包含资源文件打包
本项目中的资源文件夹:data/,本次打包将不包含此资源文件。所以在之后的使用中需要在exe文件同级目录有资源文件data/才可使用。
-
打包命令
# 生成配置文件 pyi-makespec -F --icon demo.ico --name Demo demo.py # 打包 pyinstaller Demo.spec
- -F: Python解释器、依赖包打包进入exe文件。
- –icon: 指定exe图标。
- –name: 指定exe名称。
-
打包结果
打包完成之后会生成两个文件夹build/和dist/
- build/
- …
- dist/
- Demo.exe
- build/
-
运行exe程序
将Demo.exe和资源文件data/放在同一目录下,双击运行程序。
包含资源文件打包
将本项目所有的依赖包、资源文件打包成一个exe文件,运行时无需添加资源文件,双击运行即可。
-
项目中资源路径修改。
demo.py
import os import sys from student import Student from teacher import Teacher def resource_path(relative_path): """ 资源路径 :param relative_path: 相对路径 :return: 资源路径 """ # 判断当前环境是否为打包环境 if getattr(sys, 'frozen', False): # 打包程序生成的临时文件夹路径 base_path = sys._MEIPASS else: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path) def students(): """ 获取学生对象列表 :return: 学生对象列表 """ with open(resource_path('data/students.json'), 'r', encoding='utf-8') as fp: student_list = eval(fp.read()) return [Student(student['name'], student['sex'], student['age']) for student in student_list] def teachers(): """ 获取教师对象列表 :return: 教师对象列表 """ with open(resource_path('data/teachers.json'), 'r', encoding='utf-8') as fp: teacher_list = eval(fp.read()) return [Teacher(teacher['name'], teacher['sex'], teacher['age'], teacher['course']) for teacher in teacher_list] def show(x_list): """展示""" for x in x_list: if isinstance(x, Student): print(x.name, x.sex, x.age) x.start_learn() elif isinstance(x, Teacher): print(x.name, x.sex, x.age, x.course) x.start_teach() def main(): student_list = students() teacher_list = teachers() print("------学生信息------") show(student_list) print("------教师信息------") show(teacher_list) input("请按任意键,再按Enter间结束!") if __name__ == '__main__': main()
-
生成配置文件
# 生成配置文件 pyi-makespec -F --icon demo.ico --name Demo demo.py
-
修改配置文件
Demo.spec
a = Analysis( ...... datas=[ ('data', 'data') ], ...... )
将资源文件夹data添加到配置中
-
执行打包
pyinstaller Demo.sepc
-
打包结果
打包完成之后会生成两个文件夹build/和dist/
- build/
- …
- dist/
- Demo.exe
- build/
-
运行exe程序