Python使用pyinstaller打包含有g(shù)ettext?locales語(yǔ)言環(huán)境的項(xiàng)目(推薦)
問(wèn)題
如何使用 pyinstaller 打包使用了 gettext 本地化的項(xiàng)目,最終只生成一個(gè) exe 文件
起因
最近在用 pyhton 做一個(gè)圖片處理的小工具,順便接觸了一下 gettext,用來(lái)實(shí)現(xiàn)本地化化中英文轉(zhuǎn)換。項(xiàng)目主要結(jié)構(gòu)如下:
. |--src # 源碼 | |--package1 | |--package2 | |--locales # 本地化文件 | | |--en # 英文 | | | |--LC_MESSAGES | | | |--en.mo | | |--zh # 中文 | | |--LC_MESSAGES | | |--en.mo | |--GUI.py # 界面 | |--main.py # 主程序
直接使用 pyinstaller -F src\main.py
命令進(jìn)行打包,打包后運(yùn)行在 dist 文件夾中生成的 main.exe 會(huì)報(bào)錯(cuò)。原因是 gettext 找不到本地化文件。但如果試著將 locales 文件夾復(fù)制到 main.exe 的目錄下程序能正常運(yùn)行,說(shuō)明 pyinstaller 在打包時(shí)不會(huì)將 locales 文件夾打包進(jìn)去。
復(fù)制 locales 文件夾到可執(zhí)行文件目錄下固然可以運(yùn)行,但這樣用起來(lái)會(huì)很麻煩。
解決方案
?目標(biāo)是將 locales 目錄一起打包進(jìn) exe 文件中,查閱 pyinstaller 的官方文檔,了解到執(zhí)行之前的 pyinstaller -F src\\main.py
命令會(huì)在目錄下生成一個(gè) .spec 文件,pyinstaller 通過(guò)該文件的內(nèi)容來(lái)構(gòu)建應(yīng)用程序。
the first thing PyInstaller does is to build a spec (specification) file myscript.spec. That file is stored in the --specpath directory, by default the current directory.
The spec file tells PyInstaller how to process your script. It encodes the script names and most of the options you give to the pyinstaller command. The spec file is actually executable Python code. PyInstaller builds the app by executing the contents of the spec file.
使用記事本打開,.spec 文件里面大致長(zhǎng)這樣(來(lái)自官方例子)
block_cipher = None a = Analysis(['minimal.py'], pathex=['/Developer/PItests/minimal'], binaries=None, datas=None, hiddenimports=[], hookspath=None, runtime_hooks=None, excludes=None, cipher=block_cipher) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz,... ) coll = COLLECT(...)
其中,Analysis 里面有個(gè) datas 參數(shù),用于存放非二進(jìn)制文件,也就是我們想讓程序包含的靜態(tài)文件。我們只要把 locales 目錄填到這里面打包就會(huì)添加進(jìn)去。當(dāng)然不是填一個(gè)路徑就好了,data 的格式如下:
--add-data <SRC;DEST or SRC:DEST>
SRC 就是未打包前的文件路徑,DEST 是打包后文件的路徑。以我的項(xiàng)目為例,打包前 locales 在 src/locales,打包后我想講里面的文件放到臨時(shí)目錄的根目錄下就填 ./locales,臨時(shí)目錄是什么后面講。于是在我的 .spec文件里 datas 處就寫成 datas=[("src/locales","./locales")]
。如果有多個(gè)路徑就以這樣形式 datas=[(src1, dest1), (src2, dest2), ...]
就OK。
這樣打包部分的配置就改完了,不要急,還要改下源代碼。exe 文件在運(yùn)行時(shí)會(huì)生成一個(gè)臨時(shí)目錄,我們之前 datas 中的文件也會(huì)在該目錄下??纯茨愕脑创a,如果調(diào)用資源用的是相對(duì)路徑,那讀取的是 exe 文件當(dāng)前的目錄,必然是找不到資源的。所以要把源碼中相對(duì)路徑改成臨時(shí)目錄的絕對(duì)路徑。
sys 中的 _MEIPASS 屬性存儲(chǔ)了臨時(shí)目錄路徑,直接獲取即可。如果程序運(yùn)行環(huán)境是打包后的,那么在 sys 中會(huì)添加一個(gè) frozen 屬性,通過(guò)能不能獲取 frozen 屬性可以判斷當(dāng)前環(huán)境是打包前還是打包后,具體詳情請(qǐng)查閱 pyinstaller 官方文檔(末尾有地址)。打包前就不需要獲取臨時(shí)目錄路徑了,直接用文件所在目錄路徑就行。
注意:打包后環(huán)境 file 屬性不生效
import sys import os if getattr(sys, 'frozen', None): dir = sys._MEIPASS else: dir = os.path.dirname(__file__)
獲取路徑 dir
,可以使用 os.path.join()
來(lái)拼接路徑,把源碼中調(diào)用 datas 中資源地方的路徑改成 os.path.join(dir, <打包后相對(duì)路徑>)
如我的項(xiàng)目中原來(lái)的 './locales'
處就變成了 os.path.join(dir, 'locales')
最后一步,打包!不要再輸之前的命令了,要使用改過(guò)之后的 .spec 文件進(jìn)行打包,輸入 pyinstaller -F 文件名.spec
就完成了。
參考資料
pyinstaller 文檔:Using Spec Files
pyinstaller 文檔:Run-time Information
到此這篇關(guān)于Python使用pyinstaller打包含有g(shù)ettext locales語(yǔ)言環(huán)境的項(xiàng)目的文章就介紹到這了,更多相關(guān)Python打包含有g(shù)ettext locales語(yǔ)言環(huán)境的項(xiàng)目?jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python實(shí)現(xiàn)批量壓縮指定目錄下的文件夾
這篇文章主要介紹了利用Python實(shí)現(xiàn)批量壓縮指定目錄下的文件夾的示例代碼,文中代碼示例講解詳細(xì),感興趣的小伙伴快跟隨小編一起動(dòng)手試一試2023-08-08通過(guò)Python OpenGL的point sprite技術(shù)繪制雪花
通常,點(diǎn)精靈(point sprite)技術(shù)被用于描述大量粒子在屏幕上的運(yùn)動(dòng),自然也可以用于繪制雪花。本文將通過(guò)Python OpenGL繪制雪花,感興趣的可以動(dòng)手試一試2022-02-02Python將視頻或者動(dòng)態(tài)圖gif逐幀保存為圖片的方法
本文是基于opencv將視頻和動(dòng)態(tài)圖gif保存為圖像幀的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2019-09-09數(shù)據(jù)清洗--DataFrame中的空值處理方法
今天小編就為大家分享一篇數(shù)據(jù)清洗--DataFrame中的空值處理方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07Python游戲開發(fā)實(shí)例之graphics實(shí)現(xiàn)AI五子棋
五子棋是經(jīng)典的棋牌類游戲,很多人都玩過(guò),那么如何用Python實(shí)現(xiàn)五子棋呢,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11python 在服務(wù)器上調(diào)用數(shù)據(jù)庫(kù)特別慢的解決過(guò)程
這篇文章主要介紹了python 在服務(wù)器上調(diào)用數(shù)據(jù)庫(kù)特別慢的解決過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04python實(shí)現(xiàn)數(shù)據(jù)預(yù)處理之填充缺失值的示例
下面小編就為大家分享一篇python實(shí)現(xiàn)數(shù)據(jù)預(yù)處理之填充缺失值的示例。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12深入了解python基于tkinter寫的畫圖項(xiàng)目
這篇文章主要為大家介紹了python基于tkinter寫的畫圖項(xiàng)目,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2021-12-12