天天看點

Python代碼打包成可執行檔案(exe檔案)

作者:蘇沐OvO

▍目錄

1.概述

2.方式一:指令行直接打包

3.方式二:使用spec打包

4.可能打包失敗的原因

5.相關資料擷取

▍概述

在介紹pyinstaller之前,先簡單介紹下其它幾個可以用于打包python代碼的工具:

  • cx_Freeze:可以将Python腳本轉換為獨立的可執行檔案,支援多個平台。
  • PyInstaller:可以将Python腳本(或子產品)轉換為單個可執行檔案或目錄,支援多個平台。
  • PyOxidizer:功能類似于PyInstaller,但它可以生成自包含的二進制檔案,可以跨平台使用。
  • Py2exe:僅适用于Windows平台,可以将Python腳本轉換為.exe可執行檔案。

Pyinstaller打包代碼的步驟有:

  1. 使用pip install pyinstaller指令安裝pyinstaller庫。
  2. pyinstaller提供兩種打包方式;
  3. 方式一:在cmd終端進入要打包的Python檔案所在目錄,使用pyinstaller xxx.py指令打包代碼。
  4. 方式二:在cmd終端進入要打包的Python檔案所在目錄,使用pyi-makespec xxx.py指令生成spec檔案,然後對spec需要修改的區域做修改,再使用pyinstaller xxx.spec指令打包代碼。
  5. 使用pyinstaller打包成功之後,産生兩個檔案夾:
  6. build檔案夾:這是打包過程中臨時檔案的存放位置。這些檔案包括 Python 源代碼、打包腳本和其他一些中間檔案。在成功打包應用程式後,該目錄可以被安全地删除。
  7. dist檔案夾:這是最終生成的可執行檔案及其依賴項的存放位置。

▍方式一:指令行直接打包

使用指令行打包通常适用于簡單的項目,不需要複雜的配置或自定義設定,也無需頻繁重複打包的情況;假設我們的python代碼如下,檔案名為demo.py。

#demo.py
import os
path=os.getcwd()
print(f'目前檔案路徑:{path}')
os.system('pause')           

打包步驟:

1. 在cmd終端中進入demo.py檔案的所在目錄。
2. 終端執行:pyinstaller -F demo.py           

指令解釋:

pyinstaller
[-F/-D]       # [産生當個可執行檔案/産生一個目錄(包含多個檔案)作為可執行檔案]
[-w/-c]       # [去掉指令行彈窗/顯示指令行彈窗]
-i icon.ico   # 指定exe顯示圖示
demo.py     #打包的python檔案           

結果:

打包完成後在demo.py檔案所在目錄下生成build和dist兩個檔案夾,dist目錄下的demo.exe即為我們打包後的可執行檔案。點選demo.exe檔案彈出小黑窗即為打包成功。

Python代碼打包成可執行檔案(exe檔案)

▍方式二:使用spec打包

spec檔案打包适用于更大規模、更複雜的項目,以及需要自定義配置和頻繁重複打包的時候使用;需要使用 .spec 檔案進行打包的情況有:

  1. 有資料檔案需要一起打包
  2. 把動态連結庫一起打包
  3. 添加運作時選項
  4. 想要生成多個可執行程式,公共的子產品分割出來給其他調用

假設我們的項目檔案結構如下圖所示。

PackingExe
|_ core
    |_ __init__.py
    |_ dict.txt
  |_ demo.py

           

demo.py檔案

def resource_path(relative_path):
    """ 運作exe時擷取資源檔案的絕對路徑"""
    base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
    return os.path.join(base_path, relative_path)


def main():
    print(f'目前檔案路徑:{os.getcwd()}')
    abs_path = resource_path('core/dict.txt')
    with open(abs_path, 'r', encoding='utf-8') as file:
        content = file.readline()
        print(content)
    os.system('pause')


if __name__ == "__main__":
    main()           

此處解釋一下資源路徑函數(resource_path);當exe在運作時,會生成一個臨時檔案夾,除代碼之外的資料資源需要通過sys._MEIPASS通路臨時檔案夾擷取。

打包步驟:

1. 在終端中進入PackingExe目錄。
2. 生成spec檔案:pyi-makespec -F demo.py    # 生成apec檔案,支援-F,--key等參數,不支援--upx-dir
3. 修改spec檔案
4. 執行打包指令:pyinstaller demo.spec   # 使用spec檔案打包,不支援外部參數           

spec檔案主要包含四個類:

  • Analysis類:用于分析 Python 子產品之間的依賴關系,并對需要的東西進行打包。
  • PYZ類:是一個由多個Python檔案組成的二進制檔案。PYZ檔案内部包含整個程式的代碼和标準庫,以及在腳本代碼中使用的所有第三方庫。
  • EXE類:指定要生成的可執行檔案的相關資訊,例如名稱、平台、圖示等。
  • COLLECT類:用于收集所有需要包含在可執行檔案中的檔案,并将其複制到建構目錄中以供打包和部署使用。在-F模式下,是沒有COLLECT類。
Python代碼打包成可執行檔案(exe檔案)

用于打包PackingExe項目的spec檔案如下:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
    ['demo.py'],
    pathex=[],
    binaries=[],
    datas=[('core\dict.txt', 'core')],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)


exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='demo',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

           

結果:

打包完成後在demo.py檔案所在目錄下生成build和dist兩個檔案夾,dist目錄下的demo.exe即為我們打包後的可執行檔案。點選demo.exe檔案彈出小黑窗即為打包成功。

Python代碼打包成可執行檔案(exe檔案)

▍可能打包失敗的原因

  • 程式有bug時,打包後的exe會出現閃退,而不是在小黑窗上報錯;
  • 用于打包的python解釋器路徑不能有中文或空格;如果必須有可以修改python安裝目錄下的scripts/pyinstaller-script.py檔案中的python.exe路徑;
  • 最好在py檔案首行添加# -*- coding:utf-8 -*-,否則exe容易編碼錯誤;

▍相關資料擷取

點個贊免費贈送,除上述資料外,還附贈全套Python學習資料,包含面試題、履歷資料等具體回複01即可自助領取。