本文講解:腳本打包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
添加位置以及虛擬環境
並在.py文件中輸入內容,比如
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文件,點擊即可運行。
運行結果
5秒後自動關閉。
上述打包方式,打包後文件夾內形成多個文件,不利於客戶查找。
(1)打包成單文件
pyinstaller -F app.py #app.py為py文件名稱,自行匹配更改
成功後dist文件中只有app.exe一個文件了
(2)️注意
無論哪種打包方式,若代碼有錯時,程序會立刻終止退出。如果想看程序的報錯,要先打開終端,在輸入exe文件的路徑即可。
win終端打開方式:
在電腦搜索框輸入“運行”進行搜索,並打開。
輸入cmd執行
pyinstaller -F app.py -n 我是名字
運行後,exe就是我們所設的名字。
打包的其他操作可以參考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]))
打包後不會報錯。
方法二:frozen
在官方文檔中
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
即可
打包成功後,點擊app.exe文件就可以正常運行了。
以上就是今天要講的內容,本文介紹了python打包的一般步驟以及會遇到的問題相應的解決方法,希望對大家有所幫助。