本文讲解:脚本打包exe: win/mac【终端】
第三方模块
pip install pyinstaller
注意事项:
1.在mac系统上开发(为他这个程序创建一个虚拟环境) bili
2.开发…
3.开发完毕后 pip freeze > reqirements.txt
4.打开win虚拟机
5.创建虚拟环境bili
6.安装项目依赖 pip install -r reqirements.txt
7.安装pyinstaller pyinstaller -FXXXXX
产出:哗哩哗哩.exe
1.创建虚拟环境+项目bili
2.开发
3.安装pyinstaller pyinstaller -FXXXXX
产出:哗哩哗哩.exe
添加位置以及虚拟环境
import time
print("欢迎使用***系统")
text = input("请输入信息:")
print(text)
time.sleep(5)
比如 安装 requests
pip install requests
若需要看已经安装的第三方依赖包
pip freeze > requirements.txt
在requirements.txt中就可以看到已经安装好的依赖包
至此程序开发完成。
先安装pyinstaller
pip install pyinstaller
安装成功后,将终端关闭再打开一次就有pyinstaller命令了。
然后就可以基于pyinstaller 对.py文件进行打包。
(1)打包成多文件
pyinstaller -D app.py #app.py为py文件名称,自行匹配更改
.spec文件 配置文件
.build文件 编译过程中产出的代码(没啥用)
.dist文件 最终打完包的结果
(2)查看打包结果
在文件夹中可以看到app.exe文件,点击即可运行。
运行结果
上述打包方式,打包后文件夹内形成多个文件,不利于客户查找。
(1)打包成单文件
pyinstaller -F app.py #app.py为py文件名称,自行匹配更改
(2)⚠️注意
无论哪种打包方式,若代码有错时,程序会立刻终止退出。如果想看程序的报错,要先打开终端,在输入exe文件的路径即可。
win终端打开方式:
在电脑搜索框输入“运行”进行搜索,并打开。
pyinstaller -F app.py -n 我是名字
打包的其他操作可以参考pyinstaller的说明,如-i
可以添加图标等。根据需要自己更改。
当程序中存在打开本地文件时,路径是一个要特别注意的点。
(1)引入绝对路径
例如在目录中新建一个account.txt文件
在读取本地文件时,不建议写成with open("account.txt", mode='r', encoding='utf-8') as f:
这种格式,很容易出问题。
一般使用os获取文件的绝对目录
import os
v = os.path.abspath(__file__) #.py文件的绝对目录
Baes_Dir = os.path.dirname(os.path.abspath(__file__) ) #.py文件上一层的绝对目录
print(Baes_Dir)
然后根据绝对目录获取文件
import time
import os
Baes_Dir = os.path.dirname(os.path.abspath(__file__)) # .py文件上一层的绝对目录
#print(Baes_Dir)
print("---欢迎使用***系统---")
with open(os.path.join(Baes_Dir, "account.txt"), mode='r', encoding='utf-8') as f:
data = f.read().strip()
print(data)
time.sleep(5)
(2)注意事项
按照上述方法打开外部文件时
为什么会报错? 解析到临时目录问题。
解决方法如下:
方法一:使用sys.argv
import sys
#Baes_Dir = os.path.dirname(os.path.abspath(__file__))
Baes_Dir = os.path.dirname(os.path.realpath(sys.argv[0]))
打包后不会报错。
import sys
if getattr(sys,'frozen',False):
print ( ' running in a PyInstaller bundle ' )
else:
print ( ' running in a normal Python process ' )
可以将咱们的代码改为
import time
import os
import sys
v = os.path.abspath(__file__) # .py文件的绝对目录
# BASE_Dir = os.path.dirname(os.path.abspath(__file__)) # .py文件上一层的绝对目录
if getattr(sys, 'frozen', False):
BASE_Dir = os.path.dirname(sys.executable)
else:
BASE_Dir = os.path.dirname(os.path.abspath(__file__))
print("---欢迎使用***系统---")
with open(os.path.join(BASE_Dir, "account.txt"), mode='r', encoding='utf-8') as f:
data = f.read().strip()
print(data)
time.sleep(5)
现在删掉打包的文件以及txt等文件,只留下app.py文件。
假设 程序中有其他依赖py文件,打包会出现什么情况?
例如:
新建一个目录,命名为utils,在该目录下,新建db.py和encrypt.py
在db.py和encrypt.py中定义两个函数
并在主函数中调用
现在再打包,成功后,运行app.exe能看到程序运行正常。
下一个问题是
如果依赖包中又有另外的依赖包,打包会成功吗?
例如
在utils目录下,再新建一个xx.py文件,并定义函数。
然后在db.py中导入xx函数
这样就变成app.py文件依赖db文件,db文件又依赖于xx文件。
现在再打包,完成后打开app.exe。可以发现,程序仍然可以运行成功。
至此,静态导入模块都不会有问题,会自动找到关联的依赖包,一起打包好。
但是,如果遇到那种动态导入模块的代码时,就无法找到关联的包
例如:
在utils目录下,新建card.py文件,并定义函数
然后在主函数中动态调用
这种情况下打包后会报错。
解决方法
在刚才打包后生成的.spec配置文件中,加入我们的所需的模块。
之后不能用pyinstaller -F app.py
命令打包,因为会生成一个新的配置文件,覆盖掉我们已经修改的文件。
要使用pyinstaller -F app.spec
命令,通过spec文件来进行打包。
报错
makespec options not valid when a.spec file is given
的话,
改用pyinstaller app.spec
即可
以上就是今天要讲的内容,本文介绍了python打包的一般步骤以及会遇到的问题相应的解决方法,希望对大家有所帮助。