Pythonから実行ファイルの生成 ~pyinstaller
インストール
pip install pyinstaller
インストールすると(環境によるが)Scriptsフォルダの下にpyinstaller.exeが生成されていることがわかります。
※直接インストールしたなら...AppData\Local\Programs\Python\Python〇〇\Scripts
※venvなら venvフォルダの直下
実行
yourscript.pyを作成してみよう
if __name__ == '__main__':
print('こんにちは')
pyinstaller yourscript.py
実行すると下記のファイルが生成されると思います。
フォルダ名 | |
---|---|
build | 中間ファイルが保存されている。 |
dist | 配布用 |
distのフォルダの中にあるEXEファイルをコマンドプロンプトで実行してみてください。
(カレントディレクトリで実行する必要があります。)
yourscript
onefileオプション
私の環境では、10Mb程度容量があり、ファイルがいっぱいいっぱいありますね。まとめてみましょう。
※効果を確認するためdistフォルダはあらかじめ空にしておきましょう。
pyinstaller yourscript.py --onefile
ではDistフォルダの中身を確認してみましょう。
exeファイルが一つだけになっていますね。
specファイルの編集が必要なパターン
pip install Pillow
pip install pyzbar
コードを書きましょう。
from pyzbar.pyzbar import decode
from PIL import Image
import os
if __name__ == "__main__":
cwd = os.getcwd() # カレントディレクトリ
im = Image.open(cwd + '\\test.png')
print(im.format, im.size, im.mode)
このコード画像を読み込むだけで、pyzbarのライブラリをインポートしていますが使ってはいません。
このファイルをpyinstallerで実行するとエラーが発生します。
DLLの読み込みに失敗しているんですね。実行するとspecファイルが生成されていたと思います。
さてspecファイルは下記のようになっていると思います。
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['yourscript.py'],
pathex=[],
binaries=[],
datas=[],
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='yourscript',
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,
)
これを下記のように書き換えてみましょう。
# -*- mode: python ; coding: utf-8 -*-
from pathlib import Path
from pylibdmtx import pylibdmtx
from pyzbar import pyzbar
block_cipher = None
a = Analysis(
['yourscript.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
a.binaries += TOC([
(Path(dep._name).name, dep._name, 'BINARY')
for dep in pylibdmtx.EXTERNAL_DEPENDENCIES + pyzbar.EXTERNAL_DEPENDENCIES
])
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='yourscript',
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,
)
上記では下記の二項目を追加しています。
from pathlib import Path
from pylibdmtx import pylibdmtx
from pyzbar import pyzbar
a.binaries += TOC([
(Path(dep._name).name, dep._name, 'BINARY')
for dep in pylibdmtx.EXTERNAL_DEPENDENCIES + pyzbar.EXTERNAL_DEPENDENCIES
])
pipコマンドも実行しておきましょう。
pip install pylibdmtx
指定ファイルはpyファイルではなく、specファイルであることに注意してください。
pyinstaller yourscript.spec
実行前に、dist直下に、(適当に用意した)test.pngファイルを設置してみましょう。
コマンドプロンプトを開き、dist直下のEXEファイルを実行してみましょう。
PNG (189, 179) RGB
※用意した画像によって出力される数値の結果は異なります。
Discussion