Pyinstaller打包,徹底解決圖片、數(shù)據(jù)路徑問題!
↑?關(guān)注 + 星標(biāo)?,每天學(xué)Python新技能
后臺(tái)回復(fù)【大禮包】送你Python自學(xué)大禮包
Pyinstaller打包,解決圖片、數(shù)據(jù)路徑問題!
很多網(wǎng)友碰到找不到文件的問題,都是因?yàn)閷?duì)Python讀取文件路徑的知識(shí)理解不深。本周的每天3分鐘,我們就主要圍繞路徑問題。
如果要把Python打包成一個(gè)可執(zhí)行文件,或者一個(gè)文件夾,最常用的方式是pyinstaller。
使用方法很簡(jiǎn)單,但是很多麥友會(huì)碰到路徑問題:如果代碼中需要用到圖片或數(shù)據(jù)文件,打包后執(zhí)行會(huì)失??!
咱們今天就來解決這個(gè)問題。篇幅有限,我演示一個(gè)簡(jiǎn)單的例子,并指出解決更復(fù)雜的問題的方向。
案例介紹
本例子將要打包如下文件結(jié)構(gòu):
--058
??--058.py
??--058.txt
文件夾058下有兩個(gè)文件:058.py和058.txt。其中058.py源代碼如下:
import?pathlib
folder?=?pathlib.Path(__file__).parent.resolve()
print(f'當(dāng)前python文件所在目錄:{folder}')
with?open(f'{folder}/058.txt')?as?file:
?print(file.read())
也就是說058.py文件需要用到058.txt文件。
直接運(yùn)行,會(huì)打印出數(shù)據(jù)文件的內(nèi)容:
當(dāng)前python文件所在目錄:/Users/maishu/git/wx_maishucode/code/058
跟麥?zhǔn)甯愣窂絾栴}
我們的任務(wù)是:打包成一個(gè)exe文件,可以分發(fā)給沒有Python,不懂Python的人使用。
“以下例子用Mac做演示,在Windows或Linux下也是一樣的。
安裝pyinstaller
pyinstaller是一個(gè)Python的模塊,我們先來安裝它。
在命令行下運(yùn)行:
python?-m?pip?install?pyinstaller
執(zhí)行結(jié)果如下,安裝成功:
maishu@msmacbook?058?%?python?-m?pip?install?pyinstaller
Collecting?pyinstaller
??Downloading?pyinstaller-4.9-py3-none-macosx_10_13_universal2.whl?(1.6?MB)
?????|████████████████████████████████|?1.6?MB?152?kB/s?
Collecting?pyinstaller-hooks-contrib>=2020.6
??Downloading?pyinstaller_hooks_contrib-2022.2-py2.py3-none-any.whl?(223?kB)
?????|████████████████████████████████|?223?kB?117?kB/s?
Collecting?macholib>=1.8
??Downloading?macholib-1.15.2-py2.py3-none-any.whl?(37?kB)
Requirement?already?satisfied:?setuptools?in?/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages?(from?pyinstaller)?(57.4.0)
Collecting?altgraph
??Downloading?altgraph-0.17.2-py2.py3-none-any.whl?(21?kB)
Installing?collected?packages:?altgraph,?pyinstaller-hooks-contrib,?macholib,?pyinstaller
Successfully?installed?altgraph-0.17.2?macholib-1.15.2?pyinstaller-4.9?pyinstaller-hooks-contrib-2022.2
WARNING:?You?are?using?pip?version?21.2.3;?however,?version?22.0.3?is?available.
You?should?consider?upgrading?via?the?'/Library/Frameworks/Python.framework/Versions/3.10/bin/python3?-m?pip?install?--upgrade?pip'?command.
其中的WARNING無傷大雅,先不用管。
打包失敗
現(xiàn)在我們來嘗試打包。用pyinstaller的打包過程是很簡(jiǎn)單的。
去到058所在的文件夾,運(yùn)行如下命令:
pyinstaller?058.py
會(huì)發(fā)現(xiàn)058文件夾下多了很多內(nèi)容:

其中dist目錄就是打包好的內(nèi)容所在文件夾。dist是distribution的縮寫,中文是發(fā)布的意思。
進(jìn)去看看,會(huì)發(fā)現(xiàn)dist里面又有一個(gè)058文件夾,里面放著很多內(nèi)容,包括了python解釋器等。

理論上,我們把整個(gè)058文件夾發(fā)給別人。
他們運(yùn)行其中的058可執(zhí)行文件(圖中第一個(gè)),就可以正確執(zhí)行我們的程序。
現(xiàn)在我去雙擊一下058文件,得到的結(jié)果是:
maishu@msmacbook?~?%?/Users/maishu/git/wx_maishucode/code/058/dist/058/058?;?exit;
當(dāng)前python文件所在目錄:/Users/maishu/git/wx_maishucode/code/058/dist/058
Traceback?(most?recent?call?last):
??File?"058.py",?line?5,?in?
FileNotFoundError:?[Errno?2]?No?such?file?or?directory:?'/Users/maishu/git/wx_maishucode/code/058/dist/058/058.txt'
[8404]?Failed?to?execute?script?'058'?due?to?unhandled?exception!
Saving?session...
...copying?shared?history...
...saving?history...truncating?history?files...
...completed.
運(yùn)行失敗了:FileNotFoundError,因?yàn)閿?shù)據(jù)文件沒有打包進(jìn)去。
打包成功:--add-data選項(xiàng)
我們前面用了最簡(jiǎn)單的打包命令,它會(huì)把python程序打包進(jìn)去,不會(huì)復(fù)制數(shù)據(jù),當(dāng)然會(huì)報(bào)錯(cuò)了。
實(shí)際上pyinstaller可以支持很多命令選項(xiàng),我們現(xiàn)在重新打包一次,加一個(gè)選項(xiàng):
pyinstaller?--add-data?"058.txt:."?058.py
這里添加了--add-data "058.txt:."。解釋一下:
--add-data表示后面要添加數(shù)據(jù)文件 058.txt是要添加的數(shù)據(jù)文件,它后面的冒號(hào)以及后面的點(diǎn) .表示把這個(gè)文件添加到當(dāng)前目錄下。也就是說添加文件是成對(duì)出現(xiàn),前面是要添加的文件,后面是添加的目標(biāo)目錄,中間用冒號(hào)隔開。 可以添加多個(gè)文件,用分號(hào)隔開。
運(yùn)行上面命令,會(huì)發(fā)現(xiàn)dist目錄下多了數(shù)據(jù)文件:

然后去運(yùn)行058可執(zhí)行文件:
maishu@msmacbook?~?%?/Users/maishu/git/wx_maishucode/code/058/dist/058/058?;?exit;
當(dāng)前python文件所在目錄:/Users/maishu/git/wx_maishucode/code/058/dist/058
跟麥?zhǔn)甯愣窂絾栴}
Saving?session...
...copying?shared?history...
...saving?history...truncating?history?files...
...completed.
成功了!!
打成獨(dú)立的文件:--onefile
上面是打包成了一個(gè)文件夾,發(fā)送給別人還是有點(diǎn)麻煩的。我們也可以直接打包成一個(gè)單獨(dú)的文件:
pyinstaller?--add-data?"058.txt:."?--onefile?058.py
我們加了--onefile選項(xiàng),表示打包成1個(gè)獨(dú)立的文件。
運(yùn)行后發(fā)現(xiàn)dist下面干凈多了:

運(yùn)行一下,也能成功執(zhí)行:
maishu@msmacbook?~?%?/Users/maishu/git/wx_maishucode/code/058/dist/058?;?exit;
當(dāng)前python文件所在目錄:/private/var/folders/jw/ldvymnfj1zbbmngx3p8_zl_m0000gn/T/_MEIMaXGJM
跟麥?zhǔn)甯愣窂絾栴}
Saving?session...
...copying?shared?history...
...saving?history...truncating?history?files...
...completed.
解決更復(fù)雜的問題之路
pyinstaller有很多選項(xiàng),我們?cè)诮鉀Q問題的時(shí)候可能會(huì)碰到更復(fù)雜的問題,我們3分鐘講不完。
如果你希望我更深入講解,可以轉(zhuǎn)發(fā),點(diǎn)贊,嘻嘻。如果閱讀和評(píng)論多,我可以考慮后續(xù)再出一個(gè)Pyinstaller終結(jié)者深度文章。
但是這里我就先指明幾個(gè)方向,幫助你更有效的研究:
pyinstaller的官網(wǎng)上有很細(xì)致的講解:https://pyinstaller.readthedocs.io/en/stable/spec-files.html。英語不好也可以用谷歌翻譯。
pyinstaller打包的時(shí)候會(huì)首先生成一個(gè)spec文件,我們可以手工去修改這個(gè)文件,下次打包指定用這個(gè)文件。它的好處是:里面可以寫更復(fù)雜的選項(xiàng),也可以重錄利用。

spec文件的內(nèi)容例子:
#?-*-?mode:?python?;?coding:?utf-8?-*-
block_cipher?=?None
a?=?Analysis(['058.py'],
?????????????pathex=[],
?????????????binaries=[],
?????????????datas=[('058.txt',?'.')],
?????????????hiddenimports=[],
?????????????hookspath=[],
?????????????hooksconfig={},
?????????????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,?
??????????[],
??????????exclude_binaries=True,
??????????name='058',
??????????debug=False,
??????????bootloader_ignore_signals=False,
??????????strip=False,
??????????upx=True,
??????????console=True,
??????????disable_windowed_traceback=False,
??????????target_arch=None,
??????????codesign_identity=None,
??????????entitlements_file=None?)
coll?=?COLLECT(exe,
???????????????a.binaries,
???????????????a.zipfiles,
???????????????a.datas,?
???????????????strip=False,
???????????????upx=True,
???????????????upx_exclude=[],
???????????????name='058')
好啦,今天就聊到這里,如果對(duì)你有幫助,請(qǐng)幫忙轉(zhuǎn)發(fā)。謝謝!
“新的一年,想加速Python學(xué)習(xí),獲得專業(yè)的指導(dǎo),30天學(xué)會(huì)一門技能!
歡迎參加麥?zhǔn)錚ython實(shí)戰(zhàn)訓(xùn)練營,入門營,爬蟲營,辦公自動(dòng)化營同步開放。
詳情點(diǎn)這里:麥?zhǔn)錚ython訓(xùn)練營
如果你希望我更新某個(gè)特定小知識(shí),歡迎給我留言。
推薦閱讀
您看此文用? ?
?分?
?
秒,轉(zhuǎn)發(fā)只需1秒哦~

?
?分?
?
秒,轉(zhuǎn)發(fā)只需1秒哦~