關(guān)于pyinstaller?打包多個py文件的問題
安裝pyinstall
pip install pyinstaller
注意事項(xiàng)
除非必要,否則盡量不要直接import module,用from xxx import xxx來代替,減少打包需要加載的模塊,
縮減最終的exe體積
參數(shù)詳解
usage: pyinstaller [-h] [-v] [-D] [-F] [--specpath DIR] [-n NAME] [--add-data <SRC;DEST or SRC:DEST>] [--add-binary <SRC;DEST or SRC:DEST>] [-p DIR] [--hidden-import MODULENAME] [--additional-hooks-dir HOOKSPATH] [--runtime-hook RUNTIME_HOOKS] [--exclude-module EXCLUDES] [--key KEY] [-d {all,imports,bootloader,noarchive}] [-s] [--noupx] [--upx-exclude FILE] [-c] [-w] [-i <FILE.ico or FILE.exe,ID or FILE.icns>] [--version-file FILE] [-m <FILE or XML>] [-r RESOURCE] [--uac-admin] [--uac-uiaccess] [--win-private-assemblies] [--win-no-prefer-redirects] [--osx-bundle-identifier BUNDLE_IDENTIFIER] [--runtime-tmpdir PATH] [--bootloader-ignore-signals] [--distpath DIR] [--workpath WORKPATH] [-y] [--upx-dir UPX_DIR] [-a] [--clean] [--log-level LEVEL] scriptname [scriptname ...]
positional arguments:
scriptname
要處理的腳本文件的名稱或正好一個.spec文件。 如果指定了.spec文件,則大多數(shù)選項(xiàng)是不必要的,將被忽略。
可選參數(shù):
-h,--help顯示此幫助消息并退出
-v,--version顯示程序版本信息并退出。
--distpath DIR放置捆綁的應(yīng)用程序的位置(默認(rèn)值:。\ dist)
--workpath WORKPATH將所有臨時工作文件,.log,.pyz放在哪里
等(默認(rèn)值:。\ build)
-y,--noconfirm替換輸出目錄(默認(rèn)值:
SPECPATH \ dist \ SPECNAME)而不要求
確認(rèn)
--upx-dir UPX_DIR UPX實(shí)用程序的路徑(默認(rèn)值:搜索執(zhí)行)
路徑)
-a,-ascii不包括unicode編碼支持(默認(rèn)值:
包括(如果有)
--clean清理PyInstaller緩存并刪除臨時文件
在建造之前。
--log-level LEVEL生成時控制臺消息中的詳細(xì)信息量。水平
可能是TRACE,DEBUG,INFO,WARN,ERROR,
嚴(yán)重(默認(rèn):INFO)。
產(chǎn)生什么:
-D,--onedir創(chuàng)建一個包含可執(zhí)行文件的單文件夾捆綁包
(默認(rèn))
-F,--onefile創(chuàng)建一個文件捆綁的可執(zhí)行文件。
--specpath DIR文件夾,用于存儲生成的規(guī)范文件(默認(rèn)值:
當(dāng)前目錄)
-n NAME,--name NAME分配給捆綁的應(yīng)用程序和規(guī)范文件的名稱
(默認(rèn)值:第一個腳本的基本名稱)
捆綁內(nèi)容,搜索位置:
--add-data <SRC; DEST或SRC:DEST>
要添加到的其他非二進(jìn)制文件或文件夾
可執(zhí)行文件。路徑分隔符是平臺
特定的`os.pathsep``(在Windows上是``;``
和``:``在大多數(shù)Unix系統(tǒng)上)。這個選項(xiàng)
可以多次使用。
--add-binary <SRC; DEST或SRC:DEST>
要添加到可執(zhí)行文件的其他二進(jìn)制文件。
有關(guān)更多詳細(xì)信息,請參見--add-data選項(xiàng)。這個
該選項(xiàng)可以多次使用。
-p DIR,--paths DIR搜索導(dǎo)入的路徑(例如使用PYTHONPATH)。
允許使用多個路徑,以“;”分隔,或使用
此選項(xiàng)多次
--hidden-import MODULENAME,-hiddenimport MODULENAME
命名在代碼中不可見的導(dǎo)入
腳本。此選項(xiàng)可以多次使用。
--additional-hooks-dir HOOKSPATH
搜索鉤子的其他路徑。這個選項(xiàng)
可以多次使用。
--runtime-hook RUNTIME_HOOKS
定制運(yùn)行時掛鉤文件的路徑。運(yùn)行時掛鉤是
與可執(zhí)行文件捆綁在一起的代碼是
在設(shè)置任何其他代碼或模塊之前執(zhí)行
運(yùn)行時環(huán)境的特殊功能。這個
該選項(xiàng)可以多次使用。
--exclude-module排除
可選模塊或軟件包(Python名稱,而不是
路徑名稱)將被忽略(好像不是)
找到)。此選項(xiàng)可以多次使用。
--key KEY用于加密Python字節(jié)碼的密鑰。
如何產(chǎn)生:
-d {all,imports,bootloader,noarchive},--debug {all,imports,bootloader,noarchive}
提供調(diào)試凍結(jié)的協(xié)助
應(yīng)用??梢远啻翁峁┐藚?shù)
選擇以下幾個選項(xiàng)的時間。
-全部:以下所有三個選項(xiàng)。
-導(dǎo)入:為基礎(chǔ)指定-v選項(xiàng)
Python解釋器,導(dǎo)致其打印消息
每次模塊初始化時,顯示
來源(文件名或內(nèi)置模塊)
已加載。看到
https://docs.python.org/3/using/cmdline.html#id4。
-自舉程序:告訴自舉程序發(fā)出進(jìn)度
初始化并啟動
捆綁的應(yīng)用。用于診斷問題
缺少進(jìn)口。
-存檔:而不是存儲所有凍結(jié)的Python
源文件作為結(jié)果中的存檔
可執(zhí)行文件,將它們存儲為文件
輸出目錄。
-s,--strip將符號表?xiàng)l應(yīng)用于可執(zhí)行文件并
共享庫
pyinstaller最佳使用方式
常用的命令為
pyinstall -i xxx.ico -n xxx -w -D main.py
其中 -D 參數(shù)或 -F 參數(shù)后面跟的是入口文件,即你 python xxx.py 運(yùn)行程序時這個xxx.py文件
對應(yīng)依賴比較多的程序,建議使用 -D, -F更適合單文件的py腳本。
pyinstaller 打包其實(shí)分兩步走
第一步,通過上面的命令執(zhí)行打包,此時會生成相應(yīng)的spec文件
大體流程如下:
1、在腳本目錄生成 xxx.spec 文件(看-n參數(shù),沒傳,則與xxx.py同名為xxx);
2、創(chuàng)建一個 build 目錄;
3、寫入一些日志文件和中間流程文件到 build 目錄;
4、創(chuàng)建 dist 目錄;
5、生成可執(zhí)行文件或文件夾到 dist 目錄;
效果如下:
第一步完成后,獲得xxx.spec,然后再執(zhí)行
第二步:對xxx.spec文件執(zhí)行pyinstaller 指令
pyinstaller xxx.spec
完成打包
進(jìn)入dist中打包好的文件夾后,雙腳運(yùn)行可執(zhí)行文件則可
這是一個利用tkinter構(gòu)建界面的簡單程序
spec文件解析
一個spec文件的例子。
block_cipher =None a =Analysis(['minimal.py'], pathex=['/Developer/PItests/minimal'], binaries=None, datas=None, hiddenimports=[], hookspath=None, runtime_hooks=None, excludes=None, ciper=block_cipher) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz,...) coll = COLLECT(...)
spec文件中主要包含4個class: Analysis, PYZ, EXE 和 COLLECT.
- Analysis以py文件為輸入,它會分析py文件的依賴模塊,并生成相應(yīng)的信息
- PYZ是一個.pyz的壓縮包,包含程序運(yùn)行需要的所有依賴
- EXE根據(jù)上面兩項(xiàng)生成
- COLLECT生成其他部分的輸出文件夾,COLLECT也可以沒有
手動修改spec文件
有時候PyInstaller自動生成的spec文件并不能滿足我們的需求,最常見的情況就是我們的程序依賴我們本地的一些數(shù)據(jù)文件,這個時候就需要我們自己去編輯spec文件來添加數(shù)據(jù)文件了。 上面的spec文件解析中Analysis中的datas就是要添加到項(xiàng)目中的數(shù)據(jù)文件,我們可以編輯datas.
a =Analysis( ... datas =[('you/source/file/path','file_name_in_project'), ('source/file2','file_name2')] ... )
可以認(rèn)為datas是一個List,每個元素是一個二元組。元組的第一個元素是你本地文件索引,第二個元素是拷貝到項(xiàng)目中之后的文件名字。除了上面那種寫法,也可以將其提出來。
added_files =[...] a =Analysis( ... datas = added_files, ... )
筆記: pyinstaller的常見問題
到此為止pyinstaller的知識已經(jīng)大致了解,但是并沒有解決是實(shí)操時, 主py文件調(diào)用其他py文件(自定義的)時,無法找到該模塊的問題。如下圖:
嘗試解決1:
根據(jù)下面網(wǎng)友經(jīng)驗(yàn),在spec文件中加入根目錄:
... a = Analysis(['test1.py'], pathex=['D:\Python_X64\dynamic_positioning'], # 加入根目錄,且text2.py也在該目錄中 binaries=[], datas=[], hiddenimports=[], hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) ...
嘗試解決1,測試結(jié)果:
記過如上修改,問題重要解決。程序不再報(bào)錯,并且正常運(yùn)行。
以下上是給我啟發(fā)的網(wǎng)友的操作方式,記錄并感謝
實(shí)驗(yàn)項(xiàng)目結(jié)構(gòu)
在sampleproject目錄下執(zhí)行tree /f 查看文件結(jié)構(gòu)
pyinstaller -F ?-c simple.py -p __init__.py -p test_install.py
打包多個py文件的命令
pyinstaller [主文件] -p [其他文件1] -p [其他文件2] --hidden-import [自建模塊1] --hidden-import [自建模塊2]?
其中sample.py是主程序入口文件,其他.py文件是自建模塊(test_install.py)。所以在執(zhí)行下面命令:
pyinstaller -F -c simple.py -p __init__.py -p test_install.py
執(zhí)行完成后會產(chǎn)生2個文件夾build,dist和一個文件simple.spec
進(jìn)入exe目錄并成功執(zhí)行exe程序
OK 這樣就完成了打包的程序,事實(shí)上,我并不是這么順利,中間也遇到些問題
遇到的問題
Failed to execute script ‘simple’ due to unhandled exception!
首先看下py文件的內(nèi)容,內(nèi)容瞎寫的,只是為了測試?。?!
test_install.py 文件 def install_test(): ? ? print('install test!')
simple.py 調(diào)用 test_install.py 中的方法
注意:方法1和方法2 的區(qū)別在于 導(dǎo)入模塊的方式
- simple.py 文件
方式一
import test_install ? ?# import xxx 導(dǎo)入方式 ... test_install.install_test()
- 方式二
?from test_install import install_test ? # from xxx import xxx 導(dǎo)入方式 ?... ?install_test()
這2種方式用python simple.py 都是能通過的,然而方式一和方式二打包后都有報(bào)錯ModuleNotFoundError: No module named ‘test_install’
[37320] Failed to execute script ‘simple’ due to unhandled exception!
筆記:我顯示的報(bào)錯和這位網(wǎng)友并不相同。顯示內(nèi)容如下:
解決方法:
原因 install_test 是在sample包下,導(dǎo)入路徑要寫上父包的路徑
方式三
from sample.test_install import install_test ? # 增加了sample,但是,我的sample為項(xiàng)目目錄,pycharm會報(bào)錯的 ... install_test()
方式四
from sample import test_install?? ??? ??? ??? ?# 這種寫法比較有趣,由于我的sample為項(xiàng)目目錄,pycharm會報(bào)錯的 ... test_install.install_test()
筆記:由于項(xiàng)目目錄的原因,方式3和方式4我的測試并不成功。也許不是項(xiàng)目目錄應(yīng)該可以解決。與我的解決思路感覺是一致的。
遇到的問題
NameError: name ‘exit’ is not defined
解決方法:在simple.py中使用的exit()替換為sys.exit()
出錯的原因exit 用于給交互式 Shell 返回值,而 sys.exit 是用于程序內(nèi)部
Python 中的 exit() 和 sys.exit() 的區(qū)別
exit is a helper for the interactive shell - sys.exit is intended for use in programs.
The site module (which is imported automatically during startup, except if the -S command-line option is given) adds several constants to the built-in namespace (e.g. exit). They are useful for the interactive interpreter shell and should not be used in programs.
Note that there is a third exit option, namely os._exit, which exits without calling cleanup handlers, flushing stdio buffers, etc. (and which should normally only be used in the child process after a fork()).
對于上面的引用的理解:
exit()/quit(), 拋出 SystemExit 異常. 一般在交互式 Shell 中退出時使用.
sys.exit(n) 退出程序引發(fā) SystemExit 異常, 可以捕獲異常執(zhí)行些清理工作. n 默認(rèn)值為 0, 表示正常退出. 其他都是非正常退出. 還可以 sys.exit(“sorry, goodbye!”); 一般主程序中使用此退出.
os._exit(n), 直接退出, 不拋異常, 不執(zhí)行相關(guān)清理工作. 常用在子進(jìn)程的退出.
到此這篇關(guān)于pyinstaller 打包多個py文件的文章就介紹到這了,更多相關(guān)pyinstaller 打包py文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)鼠標(biāo)自動在屏幕上隨機(jī)移動功能
這篇文章主要介紹了Python實(shí)現(xiàn)鼠標(biāo)自動在屏幕上隨機(jī)移動功能,具有很好的參考價(jià)值,希望對大家有所幫助。還等什么?一起跟隨小編過來看看吧2020-03-03Python面向?qū)ο蟪绦蛟O(shè)計(jì)OOP入門教程【類,實(shí)例,繼承,重載等】
這篇文章主要介紹了Python面向?qū)ο蟪绦蛟O(shè)計(jì)OOP入門教程,較為詳細(xì)的分析了Python面向?qū)ο箢?實(shí)例,繼承,重載等相關(guān)概念與使用技巧,需要的朋友可以參考下2019-01-01python grpc實(shí)現(xiàn)異步調(diào)用(不用grpc異步接口)
grpc同步調(diào)用更簡單,但是在處理復(fù)雜任務(wù)時,會導(dǎo)致請求阻塞,影響吞吐,本文主要介紹了python grpc實(shí)現(xiàn)異步調(diào)用,不用grpc異步接口,具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04Pytorch中的model.train()?和?model.eval()?原理與用法解析
pytorch可以給我們提供兩種方式來切換訓(xùn)練和評估(推斷)的模式,分別是:model.train()?和?model.eval(),這篇文章主要介紹了Pytorch中的model.train()?和?model.eval()?原理與用法,需要的朋友可以參考下2023-04-04matplotlib繪圖實(shí)例演示標(biāo)記路徑
這篇文章主要介紹了matplotlib繪圖實(shí)例演示標(biāo)記路徑,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01Python裝飾器實(shí)現(xiàn)函數(shù)運(yùn)行時間的計(jì)算
這篇文章主要為大家詳細(xì)介紹了Python函數(shù)運(yùn)行時間的計(jì)算,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02Python3.7 讀取音頻根據(jù)文件名生成腳本的代碼
這篇文章主要介紹了Python3.7 讀取音頻根據(jù)文件名生成字幕腳本的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04