程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python學習 | python代碼打包exe文件

編輯:Python

前言

本文講解:腳本打包exe: win/mac【終端】


文章目錄

  • 前言
  • 一、exe打包流程
  • 二、exe打包案例
    • 1.新建工程
    • 2.新建python文件
    • 3.添加並查看依賴包
    • 4.安裝打包工具
    • 5.打包——打包成多文件
    • 6.打包——打包成單文件
    • 6.打包命名
  • 三、打包時路徑問題
  • 四、關於模塊的問題
    • 1. 靜態導入模塊
    • 2. 動態導入模塊
  • 總結


一、exe打包流程

第三方模塊

pip install pyinstaller

注意事項:

  • 支持mac、win (windows建議使用python3.6.8)。
  • 配合虛擬環境打包。

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

二、exe打包案例

1.新建工程

添加位置以及虛擬環境

2.新建python文件


並在.py文件中輸入內容,比如

import time
print("歡迎使用***系統")
text = input("請輸入信息:")
print(text)
time.sleep(5)

3.添加並查看依賴包

比如 安裝 requests

pip install requests

若需要看已經安裝的第三方依賴包

pip freeze > requirements.txt

在requirements.txt中就可以看到已經安裝好的依賴包

至此程序開發完成。

4.安裝打包工具

先安裝pyinstaller

pip install pyinstaller

安裝成功後,將終端關閉再打開一次就有pyinstaller命令了。


然後就可以基於pyinstaller 對.py文件進行打包。

5.打包——打包成多文件

(1)打包成多文件

pyinstaller -D app.py #app.py為py文件名稱,自行匹配更改

成功後生成三個新文件

.spec文件 配置文件
.build文件 編譯過程中產出的代碼(沒啥用)
.dist文件 最終打完包的結果

(2)查看打包結果
在文件夾中可以看到app.exe文件,點擊即可運行。

運行結果


5秒後自動關閉。

6.打包——打包成單文件

上述打包方式,打包後文件夾內形成多個文件,不利於客戶查找。

(1)打包成單文件

pyinstaller -F app.py #app.py為py文件名稱,自行匹配更改

成功後dist文件中只有app.exe一個文件了

(2)️注意
無論哪種打包方式,若代碼有錯時,程序會立刻終止退出。如果想看程序的報錯,要先打開終端,在輸入exe文件的路徑即可。

win終端打開方式:
在電腦搜索框輸入“運行”進行搜索,並打開。

輸入cmd執行

6.打包命名

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文件,打包會出現什麼情況?

1. 靜態導入模塊

例如:
新建一個目錄,命名為utils,在該目錄下,新建db.py和encrypt.py

在db.py和encrypt.py中定義兩個函數


並在主函數中調用

現在再打包,成功後,運行app.exe能看到程序運行正常。

下一個問題是
如果依賴包中又有另外的依賴包,打包會成功嗎?

例如
在utils目錄下,再新建一個xx.py文件,並定義函數。

然後在db.py中導入xx函數

這樣就變成app.py文件依賴db文件,db文件又依賴於xx文件。
現在再打包,完成後打開app.exe。可以發現,程序仍然可以運行成功。

至此,靜態導入模塊都不會有問題,會自動找到關聯的依賴包,一起打包好。

2. 動態導入模塊

但是,如果遇到那種動態導入模塊的代碼時,就無法找到關聯的包
例如:
在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打包的一般步驟以及會遇到的問題相應的解決方法,希望對大家有所幫助。


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved