pyhon.py→exe化→軽量化→高速化 忘備録(pyinstaller py2exe)

Yutaka_kun
LSC PSD
Published in
6 min readMay 27, 2020

pyinstallerとpy2exeを使ってpythonファイルをexe化した過程をここに書き記します。最近はexe化する人はほぼいないらしく需要はないと思いますが、自分が忘れないようにするためにまとめておきます。
なのでいつものように図解したり、ネチネチ解説したりはしません。
exe化の流れと、参考にしたサイトをまとめるだけになると思います。

pyinstallerでexe化

pip install pyinstaller

exe化したいpythonファイルを用意して

pyinstaller python.py --onefile

同じディレクトリに色々ファイルやらフォルダやら作成される
運が良ければdistフォルダの中にあるpython.exeは起動するかも、、
おそらくエラーが出る

作成されたpython.specファイルを開いて、以下のように編集する

hiddenimports=[]

hiddenimports=[‘pkg_resources.py2_warn’]

その後以下のようにコマンドして実行

pyinstaller python.spec --onefile

これでdistフォルダの中にあるpython.exeが動くはず
でも起動時間の遅さに絶望する

軽量化

作成されたpython.exeは仮想環境の中に入ってる必要のないライブラリも一緒にexe化するので容量がめっさでかくなる(numpyとpandasが結構容量を食うらしい)

pyinstallerでexeする時に下記のようにいらないライブラリを指定して省く
(自分の場合numpyは必要だったのでpandasのみ省く)

pyinstaller python.py --onefile --exclude pandas

この後python.specをさきほどのように編集した後

hiddenimports=[]

hiddenimports=[‘pkg_resources.py2_warn’]

pyz = PYZ(a.pure, a.zipped_data,cipher=block_cipher)

exe = EXE(…..)
の間に以下を挿入する

Key = ['mkl']

def remove_from_list(input, keys):
outlist = []
for item in input:
name, _, _ = item
flag = 0
for key_word in keys:
if name.find(key_word) > -1:
flag = 1
if flag != 1:
outlist.append(item)
return outlist

a.binaries = remove_from_list(a.binaries, Key)

Anaconda環境でpandasをインストールした時にdependencies(依存関係)として勝手についてくるMKLというモジュールがどえらい容量みたい
ただこのMKLを除外する作業は最初に — exclude pandasしてるのであれば必要ないのかも(参考にしたサイト

その後さきほどと同じように
pyinstaller python.spec — onefile ( — exclude pandasも必要だったかな?? )でexeファイルができる

※もしpython.exeを起動してnumpyに関するエラーが出る場合は
(ImportError: numpy.core.multiarray failed to importだったかな、、?)
以下のようにコマンドする

pip install -U numpy

pyinstaller(まとめ)

何も入っていない仮想環境を構築した後、必要なライブラリだけインストールしexe化するのがいいかも
50行ぐらいのコードでimportがos,sys,cv2,numpy,math,timeのexeファイルの容量は軽量前で約270M、軽量後で約80M
起動時間は軽量前で7秒程度、軽量後で4秒程度と微妙、、、
pyinstallerのexe化は工程が簡単だが処理時間がネック
そしてnumpyとpandasを使ってコーディングすると200Mが確定?

py2exeでexe化

py2exeはpython3.4以下までしかサポートされていないという記事が多かったが、3.5以降もexe化可能であるという記事を見つけた

exe化工程に入る前にできるだけ不要なライブラリは省いておく
64bit版python3.7バージョンが必要だったのでgithubのページより以下をダウンロード

py2exe-0.9.3.2-cp37-none-win_amd64.whl

pip install ダウンロードしたwhlまでのパス

これでpython3.7用のpy2exeがインストールできた

setup.pyを作成

新しくsetup.pyを作成し、以下のようにコーディングする

from distutils.core import setup
import py2exe

setup(console=['python.py'])

python.pyとsetup.pyを同じディレクトリにおいて

python setup.py py2exe

distというフォルダの中にexeが作成されるはず
ただしこのexeは単体では動かず、distディレクトリ以下をまとめて渡さないと動かない(pyinstallerはexe単体で動作可能)

できたexeは容量46M で起動時間が0.5秒と爆速だった

本体を圧縮したり、アイコンを追加したりしたい場合はsetup.pyに追加でいろいろ書き足してく
py2exeでPythonのスクリプトを実行ファイル(exe)にする
もしくは
PYINSTALLERの遅さにがっかりしてPY2EXEにしたら爆速で驚いた件
を参考するとよい
が、やってみたけどエラー吐きまくって結局
setup(console=[‘python.py’])
の一行でしかうまくいかなかった

py2exe(まとめ)

setup.pyを作成したり、pythonのバージョンによってダウンロードするwhlが違うのでめんどい
その代わり処理時間が爆速
exe単体では動かないのでdistフォルダ以下すべてあたえる

おまけ

exeファイルに外から引数をあたえたいときは(例えば画像pathをあたえるときは)コードの中に以下を加えるとよい

import sys
image_path = ' '.join(sys.argv[1:])

そうすれば引数が渡すことができる

python.exe 画像path

--

--

Yutaka_kun
LSC PSD
Editor for

Microbiology technician,Machine learning engineer(beginner)