如果将Python代码使用pyinstaller打包成exe文件时,只有一个大的exe文件,很多人可能遇到,在本机上就已经不能运行了,有的情况好些,在本机可以运行,发给别人就无法正常运行。本文本就是分析一下原因。
生成的exe文件,运行时自动释放到 C:\Users\"你当前用户"\AppData\Local\Temp\_MEIXXXXX,
如果你源代码中都使用绝对路径读的文件,那么你可能在本机上运行就是正常,但是如果分给别人,资源路径不对应就会出错了。
还有当你引用其它库的时候,库里面再读取文件一般是相对路径,例如
http://www.pianshen.com/article/996685916/
https://blog.csdn.net/sinat_34200786/article/details/79715236
https://blog.csdn.net/Beyond_F4/article/details/88706837
https://blog.csdn.net/qq_26376175/article/details/69680992
如果一个一个去改源代码,就比较麻烦,最容易的方法就是把用到的库都放到你的要生成的.py文件同一目录下,并在.spec文件中加入他们,这样读取就没有问题了。见红字的。
# -*- mode: python -*-
import sys
import os.path as osp
sys.setrecursionlimit(25000000)
block_cipher = None
SETUP_DIR = 'D:\\working\\Python\\readHeadFileTraining\\NPL\\NPL_SanguoAndHamlet\\wordCloud'
a = Analysis(['wordcloudinterface.py'],
pathex=[SETUP_DIR],
binaries=[],
datas=[('data','data'),('wordcloud','wordcloud'),('jieba','jieba'),('cv2','cv2')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='wordcloudinterface',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=True,icon='demo.ico' )
另外,如果程序中读了文件,pyinstall也不会自动打包的。
比如我的程序读取了 data文件夹下的MSYH.tff字体文件,如果我已经将data打进包了,这时要这样改进代码
#生成资源文件目录访问路径 def resource_path(relative_path): if getattr(sys, 'frozen', False): #是否Bundle Resource base_path = sys._MEIPASS else: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path)
myFontPath= resource_path("data/MSYH.TTC")
根据不同情况进行判断,保证本机在调试、及打包正常运行。
如果只用以下的声明
myFontPath= "data/MSYH.TTC"
那么在生成后的exe文件就肯定不好用了。除非你在.exe文件夹里也一个data文件夹,里面也有一个MSYH.TTC
如果只用以下的声明
myFontPath= "c:/test/data/MSYH.TTC"
那么在生成后的exe文件就只能在本机好用了。除非你发给别人的系统也有一样的路径文件夹里也一个data文件夹,里面也有一个MSYH.TTC才可以正常运行
所以原代码中用到相对路径要改,另外引用的库可能也会用到相对路径,也要修改,例如jieba,cv2,wordcloud等库,具体问题要具体分析,基本都是这个原因引起的