Bei Python-Code mit pykakasi wurde beim Ausführen der von PyInstaller generierten ausführbaren Datei der Fehler "KeyError: '_ max_key_len_'" angezeigt. Notieren Sie sich, wie Sie dies vermeiden können. Ich verwende Linux (Ubuntu 18.04), Python 3.7.5 und verwende pipenv.
Code dieses Artikels wurde geändert und verwendet. Ich werde die folgenden 3 Dateien verwenden, um die Binärversion von foo.py zu starten.
foo.py
from mymod1 import bar
from mymod2 import hoge
bar("Hello!")
hoge("Hoge!")
mymod1.py
def bar(s):
print(f"bar: {s}")
mymod2.py
import pykakasi
def hoge(s):
kakasi = pykakasi.kakasi()
kakasi.setMode('H', 'a')
kakasi.setMode('K', 'a')
kakasi.setMode('J', 'a')
conv = kakasi.getConverter()
print(conv.do(s))
Installieren Sie das Modul wie folgt auf Ihrem Terminal:
pipenv install setuptools pykakasi pyinstaller
Die zu diesem Zeitpunkt vorhandenen Dateien lauten wie folgt.
$ ls
Pipfile
foo.py
mymod1.py
mymod2.py
Das generierte Pipfile lautet wie folgt.
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
setuptools = "*"
pykakasi = "*"
pyinstaller = "*"
[requires]
python_version = "3.7"
Führen Sie die folgenden Schritte auf dem Terminal aus, um eine ausführbare Datei zu erstellen.
pipenv run pyinstaller foo.py
Wenn Sie die Datei mit ls überprüfen, werden das Build-Verzeichnis und das dist-Verzeichnis generiert.
$ ls
Pipfile
build
dist
foo.py
foo.spec
mymod1.py
mymod2.py
Da "dist / foo / foo" die ausführbare Datei ist, trat beim Versuch, sie zu verschieben, "KeyError: '_ max_key_len_'" wie unten gezeigt auf.
$ dist/foo/foo
bar: Hello!
Traceback (most recent call last):
File "foo.py", line 5, in <module>
hoge("Hoge!")
File "mymod2.py", line 10, in hoge
conv = kakasi.getConverter()
File "pykakasi/kakasi.py", line 91, in getConverter
File "pykakasi/kanji.py", line 30, in __init__
File "pykakasi/kanji.py", line 126, in __init__
KeyError: '_max_key_len_'
[6202] Failed to execute script foo
Die Ursache war, dass das Wörterbuch von Pykakashi unter dist unzureichend war. Unter dist gibt es ein Wörterbuch wie unten gezeigt.
$ ls dist/foo/pykakasi/data/
itaijidict3.db
Auf der anderen Seite gab es 8 Wörterbücher im Installationsziel von pipenv.
$ ls `pipenv --venv`/lib/python3.7/site-packages/pykakasi/data/
hepburndict3.db
itaijidict3.db
kunreidict3.db
passportdict3.db
hepburnhira3.db
kanwadict4.db
kunreihira3.db
passporthira3.db
Kopieren Sie dies unter dist durch Überschreiben.
$ cp `pipenv --venv`/lib/python3.7/site-packages/pykakasi/data/* dist/foo/pykakasi/data/
$ ls dist/foo/pykakasi/data/
hepburndict3.db
itaijidict3.db
kunreidict3.db
passportdict3.db
hepburnhira3.db
kanwadict4.db
kunreihira3.db
passporthira3.db
Als ich die Binärdatei erneut ausführte, funktionierte sie wie folgt.
$ dist/foo/foo
bar: Hello!
hoge!
Ich habe einen besseren Weg gefunden, also werde ich ihn hinzufügen. Der folgende zusätzliche Teil wurde unter Windows ausgeführt.
Referenzseite (Danke)
Bei der ersten Generierung ausführbarer Dateien wurde auch eine foo.spec-Datei generiert. Bearbeiten Sie diese Datei wie folgt, um alle Pykakasi-Wörterbuchdateien zu a.datas hinzuzufügen. Der Speicherort der Pykakasi-Wörterbuchdatei hängt von der Umgebung ab, daher muss sie neu geschrieben werden (in meiner Umgebung ist dies der Speicherort unterhalb des Laufwerks C).
Ich habe auch versteckte Importe optimiert, aber siehe diesen Artikel (https://qiita.com/kanedaq/items/e65507878c52ad67d002).
foo.spec
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['foo.py'],
pathex=['C:\\Users\\username\\PycharmProjects\\foo_project'],
binaries=[],
datas=[],
- hiddenimports=[],
+ hiddenimports=['pkg_resources.py2_warn'],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
+a.datas += [('pykakasi\\data\\hepburndict3.db', 'C:\\Users\\username\\.virtualenvs\\d_predict-Evs_tHQX\\lib\\site-packages\\pykakasi\\data\\hepburndict3.db', 'DATA')]
+a.datas += [('pykakasi\\data\\hepburnhira3.db', 'C:\\Users\\username\\.virtualenvs\\d_predict-Evs_tHQX\\lib\\site-packages\\pykakasi\\data\\hepburnhira3.db', 'DATA')]
+a.datas += [('pykakasi\\data\\itaijidict3.db', 'C:\\Users\\username\\.virtualenvs\\d_predict-Evs_tHQX\\lib\\site-packages\\pykakasi\\data\\itaijidict3.db', 'DATA')]
+a.datas += [('pykakasi\\data\\kanwadict4.db', 'C:\\Users\\username\\.virtualenvs\\d_predict-Evs_tHQX\\lib\\site-packages\\pykakasi\\data\\kanwadict4.db', 'DATA')]
+a.datas += [('pykakasi\\data\\kunreidict3.db', 'C:\\Users\\username\\.virtualenvs\\d_predict-Evs_tHQX\\lib\\site-packages\\pykakasi\\data\\kunreidict3.db', 'DATA')]
+a.datas += [('pykakasi\\data\\kunreihira3.db', 'C:\\Users\\username\\.virtualenvs\\d_predict-Evs_tHQX\\lib\\site-packages\\pykakasi\\data\\kunreihira3.db', 'DATA')]
+a.datas += [('pykakasi\\data\\passportdict3.db', 'C:\\Users\\username\\.virtualenvs\\d_predict-Evs_tHQX\\lib\\site-packages\\pykakasi\\data\\passportdict3.db', 'DATA')]
+a.datas += [('pykakasi\\data\\passporthira3.db', 'C:\\Users\\username\\.virtualenvs\\d_predict-Evs_tHQX\\lib\\site-packages\\pykakasi\\data\\passporthira3.db', 'DATA')]
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='foo',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='foo')
Verwenden Sie die neu geschriebene Spezifikationsdatei, um erneut eine ausführbare Datei zu generieren.
pipenv run pyinstaller foo.spec
Als ich die generierte Binärdatei ausführte, funktionierte sie wie folgt.
C:\Users\username\PycharmProjects\foo_project>dist\foo\foo
bar: Hello!
hoge!
Unter dem dist-Verzeichnis, in dem sich die Binärdatei befindet, wird wie unten gezeigt ein Unterverzeichnis für pykakasi erstellt, und Sie können sehen, dass das Wörterbuch kopiert wird.
C:\Users\username\PycharmProjects\foo_project>dir .\dist\foo\pykakasi\data
C:\Users\username\PycharmProjects\foo_project\dist\foo\pykakasi\Datenverzeichnis
<DIR> .
<DIR> ..
5,852 hepburndict3.db
5,649 hepburnhira3.db
13,981 itaijidict3.db
7,154,489 kanwadict4.db
5,843 kunreidict3.db
5,642 kunreihira3.db
6,635 passportdict3.db
6,370 passporthira3.db
Das ist alles für das Postskriptum.
Recommended Posts