1. 程式人生 > >如何將 Python 程式打包成 .exe 檔案?

如何將 Python 程式打包成 .exe 檔案?

有不少訂閱本公眾號的朋友都不是玩 Python,甚至都不是計算機相關專業的,當我給他們一個 Python 程式時,他們是完全不知道該怎麼執行的。

於是我想是不是可以將我的程式打包成可執行檔案,直接執行?

就像這樣:

hello

Python 程式都是指令碼的方式,一般是在解析器裡執行,如果要釋出出去,需要提前安裝解析器才可以執行,為了在 Windows 裡方便釋出,只要點選一個 EXE 檔案執行,並且打包所需要庫檔案,這樣釋出給使用者使用就會更方便。

PyInstaller

PyInstaller 是一個十分有用的第三方庫,可以用來打包 python 應用程式,打包完的程式就可以在沒有安裝 Python 直譯器的機器上運行了。

它能夠在 Windows、Linux、 Mac OS X 等作業系統下將 Python 原始檔打包,通過對原始檔打包, Python 程式可以在沒有安裝 Python 的環境中執行,也可以作為一個 獨立檔案方便傳遞和管理。

PyInstaller 支援 Python 2.7 / 3.4-3.7。可以在 Windows、Mac OS X 和 Linux 上使用,但是並不是跨平臺的,而是說你要是希望打包成 .exe 檔案,需要在 Windows 系統上執行 PyInstaller 進行打包工作。

下面我們以 Windows 為例來進行程式的打包工作。

安裝

pip install pyinstaller
# 或者
python -m pip install pyinstaller

安裝成功:

安裝成功

使用

pyinstaller -F helloworld.py

其中,-F 表示打包成單獨的 .exe 檔案,這時生成的 .exe 檔案會比較大,而且執行速度回較慢。僅僅一個 helloworld 程式,生成的檔案就 5MB 大。

另外,使用 -i 還可以指定可執行檔案的圖示; -w 表示去掉控制檯視窗,這在 GUI 介面時非常有用。不過如果是命令列程式的話那就把這個選項刪除吧!

PyInstaller 會對指令碼進行解析,並做出如下動作:

1、在指令碼目錄生成 helloworld.spec 檔案; 2、建立一個 build 目錄; 3、寫入一些日誌檔案和中間流程檔案到 build 目錄; 4、建立 dist 目錄; 5、生成可執行檔案到 dist 目錄;

執行流程:

$ pyinstaller -F helloworld.py
838 INFO: PyInstaller: 3.4
839 INFO: Python: 3.4.3
841 INFO: Platform: Windows-8-6.2.9200
842 INFO: wrote d:\code\Python\pyinstaller\helloworld.spec
858 INFO: UPX is not available.
885 INFO: Extending PYTHONPATH with paths
['d:\\code\\Python\\pyinstaller', 'd:\\code\\Python\\pyinstaller']
886 INFO: checking Analysis
887 INFO: Building Analysis because Analysis-00.toc is non existent
888 INFO: Initializing module dependency graph...
890 INFO: Initializing module graph hooks...
899 INFO: Analyzing base_library.zip ...
6225 INFO: Processing pre-find module path hook   distutils
11387 INFO: running Analysis Analysis-00.toc
12012 INFO: Caching module hooks...
12022 INFO: Analyzing d:\code\Python\pyinstaller\helloworld.py
12027 INFO: Loading module hooks...
12028 INFO: Loading module hook "hook-encodings.py"...
12395 INFO: Loading module hook "hook-xml.py"...
13507 INFO: Loading module hook "hook-pydoc.py"...
13508 INFO: Loading module hook "hook-distutils.py"...
13606 INFO: Looking for ctypes DLLs
13662 INFO: Analyzing run-time hooks ...
13677 INFO: Looking for dynamic libraries
13894 INFO: Looking for eggs
13895 INFO: Using Python library C:\WINDOWS\system32\python34.dll
13895 INFO: Found binding redirects:
[]
13915 INFO: Warnings written to d:\code\Python\pyinstaller\build\helloworld\warn-helloworld.txt
14035 INFO: Graph cross-reference written to d:\code\Python\pyinstaller\build\helloworld\xref-helloworld.html
14287 INFO: checking PYZ
14287 INFO: Building PYZ because PYZ-00.toc is non existent
14288 INFO: Building PYZ (ZlibArchive) d:\code\Python\pyinstaller\build\helloworld\PYZ-00.pyz
15836 INFO: Building PYZ (ZlibArchive) d:\code\Python\pyinstaller\build\helloworld\PYZ-00.pyz completed successfully.
15883 INFO: checking PKG
15884 INFO: Building PKG because PKG-00.toc is non existent
15884 INFO: Building PKG (CArchive) PKG-00.pkg
18528 INFO: Building PKG (CArchive) PKG-00.pkg completed successfully.
18536 INFO: Bootloader D:\program\Python34\lib\site-packages\PyInstaller\bootloader\Windows-64bit\run.exe
18537 INFO: checking EXE
18537 INFO: Building EXE because EXE-00.toc is non existent
18538 INFO: Building EXE from EXE-00.toc
18538 INFO: Appending archive to EXE d:\code\Python\pyinstaller\dist\helloworld.exe
18548 INFO: Building EXE from EXE-00.toc completed successfully.

生成檔案:

生成兩個目錄

生成的可執行檔案

注意事項

1、直接執行最終的 .exe 程式,可能會出現一閃而過的情況,這種情況下要麼是程式執行結束(比如直接列印的 helloWorld),要麼程式出現錯誤退出了。

這種情況下,建議在命令列 cmd 下執行 .exe 檔案,這時就會有文字輸出到視窗;

2、-i 是改變圖示的,但是我發現是有些 bug 的,客官請看:

圖示變化

放大過程中,圖示才變成了我們設定的圖示。

3、寫程式碼的時候應當有個良好的習慣,用什麼函式導什麼函式,不要上來 import 整個庫,最後你會發現你一個 100KB 的程式碼打包出來有 500MB;

4、當你的程式碼需要呼叫一些圖片和資原始檔的,這是不會自動匯入的,需要你自己手動複製進去才行。不然 exe 檔案執行時命令視窗會報錯找不到這個檔案。

匯入方法:

假設程式中需要引入一個 test.txt 檔案,首先我們執行:

pyi-makespec -F helloworld.py

此時會生成一個 .spec 檔案,這個檔案會告訴 pyinstaller 如何處理你的指令碼,pyinstaller 建立一個 exe 的檔案就是依靠它裡面的內容進行執行的。

正常情況下你不需要去修改這個 spec 檔案,除非你需要打包一個 dll 或者 so 檔案或者其他資料檔案。

那麼我們就需要修改這個 spec 檔案:

a = Analysis(['helloworld.py'],
             pathex=['/home/test'],
             binaries=[],
             datas=[],  ### <------- 改

修改為:

a = Analysis(['helloworld.py'],
             pathex=['/home/test'],
             binaries=[],
             datas=[('test.txt','.')],  ## <---- 修改此處新增外部檔案

然後在生成 exe 檔案:

pyinstaller helloworld.spec

然後生成的檔案就可以正常引入外部檔案了。

總結

歡迎留言交流。

如果覺得有用,歡迎關注我的微信,一起學習,共同進步,不定期推出贈書活動~

你的關注是對我最大的鼓勵!

最近蒐集到傳智播客 2018 最新 Python 和 Java 教程!關注本公眾號,後臺回覆「2018」即可獲取下載地址。