iT邦幫忙

3

如何使用PyInstaller打包Python代碼為執行檔-2

工作環境:
-Windows 10, Windows Server 2019
-Anaconda 2020.02
-Python 3.6.10

問題描述:
餓死抬頭,上一篇分享了關於如何用PyInstaller打包.py為.exe。但是有個問題,這個執行檔其實並不是獨立的,如果我們將main.exe挪到其他位置,可以發現他無法開啟,對於習慣用免安裝程式的我來說是不能允許的,所以這篇就分享一下怎麼能做一個真正獨立的.exe。

常見的教學文章都會用下面代碼步驟搞定我們碰到的問題,-F代表把所有需要的套件和主代碼都濃縮為一個檔案(就是.exe);-w代表關閉執行時不要顯示Windows的命令提示視窗(雖然這個可以用來Debug)[1]

pyinstaller -F -w 我的程式碼.py

我們先保留上一篇好不容易調教出來的.spec檔,並且運行上面那行代碼:

(keras4) C:\Users\*\Documents\GUI-20200323>pyinstaller -F -w main.py
193 INFO: PyInstaller: 3.6
193 INFO: Python: 3.6.10 (conda)
193 INFO: Platform: Windows-10-10.0.18362-SP0
213 INFO: wrote C:\Users\*\Documents\GUI-20200323\main.spec
215 INFO: UPX is not available.
218 INFO: Extending PYTHONPATH with paths
['C:\\Users\\*\\Documents\\GUI-20200323',
 'C:\\Users\\*\\Documents\\GUI-20200323']
219 INFO: checking Analysis
.....中間省略.....
  File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 263, in generic_visit
    self.visit(value)
  File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 253, in visit
    return visitor(node)
  File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 263, in generic_visit
    self.visit(value)
  File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 253, in visit
    return visitor(node)
  File "c:\users\*\appdata\local\continuum\anaconda3\envs\keras4\lib\ast.py", line 257, in generic_visit
    for field, value in iter_fields(node):
RecursionError: maximum recursion depth exceeded

解決方法:
為什麼遞迴限制的問題又發生了,原來是因為main.spec被覆蓋掉了哭哭。那我們有辦法透過修改配置文件來達到目的嗎,答案是可以的,我的方法如下:

  1. 建立一個簡單的simple.py檔,裡面就寫個hellow world而已:
import os

print('Hellow World!!!')

os.system('pause')
  1. 利用pyinstaller -F -w simple.py打包他
  2. 比較一下simple.spec和main.spec,接下來我們要開始修改simple.spec
  3. 把simple.spec裡面的simple字眼替換為simple
  4. 參考main.spec,把simple.spec裡面的hiddenimports填寫一致
  5. 參考main.spec,把simple.spec裡面的pathex填寫一致
  6. simple.spec最上面要補上這行代碼:
import sys
sys.setrecursionlimit(9000000)
  1. 把simple.spec改名為main.spec
  2. 執行下面代碼,搞定收工,整個dist資料夾就只有一個main.exe檔:
pyinstaller main.spec

收工

下面就附上修改完畢的.spec:

# -*- mode: python ; coding: utf-8 -*-
import sys# 這邊要注意
sys.setrecursionlimit(9000000)# 這邊要注意
block_cipher = None


a = Analysis(['main.py'],# 這邊要注意
             pathex=['C:\\Users\\e10832\\Documents\\GUI-20200323'], #這邊要注意
             binaries=[],
             datas=[],
             hiddenimports=['pkg_resources.py2_warn', 'sklearn.utils._cython_blas'], # 這邊要注意
             hookspath=[],
             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='main', # 這邊要注意
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=False )

補充說明:
雖然我們順利完成了獨立的.exe檔,但是有夠肥(280MB),而且開啟速度有夠慢!!!等我研究完怎麼瘦身再跟大家分享~

參考資料:
[1]https://www.yuanrenxue.com/tricks/pyinstaller-spec.html


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0

謝謝分享,感覺很實用~

我要留言

立即登入留言