Pour le code Python utilisant pykakasi, lorsque j'ai exécuté le fichier exécutable généré par PyInstaller, j'ai eu l'erreur "KeyError: '_ max_key_len_'". Notez comment l'éviter. J'utilise Linux (Ubuntu 18.04), python 3.7.5 et utilise pipenv.
Code de cet article a été modifié et utilisé. J'utiliserai les 3 fichiers suivants pour démarrer la version binaire de foo.py.
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))
Installez le module en procédant comme suit sur votre terminal:
pipenv install setuptools pykakasi pyinstaller
Les fichiers qui existent à ce stade sont les suivants.
$ ls
Pipfile
foo.py
mymod1.py
mymod2.py
Le Pipfile généré est le suivant.
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
setuptools = "*"
pykakasi = "*"
pyinstaller = "*"
[requires]
python_version = "3.7"
Exécutez ce qui suit sur le terminal pour créer un fichier exécutable.
pipenv run pyinstaller foo.py
Si vous vérifiez le fichier avec ls, le répertoire de construction et le répertoire dist sont générés.
$ ls
Pipfile
build
dist
foo.py
foo.spec
mymod1.py
mymod2.py
Puisque "dist / foo / foo" est le fichier exécutable, lorsque j'ai essayé de le déplacer, "KeyError: '_ max_key_len_'" s'est produit comme indiqué ci-dessous.
$ 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
La cause était que le dictionnaire de pykakashi sous dist était insuffisant. Sous dist, il y a un dictionnaire comme indiqué ci-dessous.
$ ls dist/foo/pykakasi/data/
itaijidict3.db
D'autre part, il y avait 8 dictionnaires dans la destination d'installation par 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
Copiez ceci sous dist en écrasant.
$ 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
Quand j'ai exécuté à nouveau le binaire, cela a bien fonctionné comme ci-dessous.
$ dist/foo/foo
bar: Hello!
hoge!
J'ai trouvé un meilleur moyen, alors je vais l'ajouter. La partie supplémentaire suivante a été exécutée sous Windows.
Page de référence (merci)
La première génération de fichier exécutable a également généré un fichier foo.spec. Modifiez ce fichier comme suit pour ajouter tous les fichiers de dictionnaire pykakasi à a.datas. L'emplacement du fichier de dictionnaire pykakasi dépend de l'environnement, il doit donc être réécrit (dans mon environnement, c'est l'emplacement en bas du lecteur C).
Nous avons également modifié hiddenimports, mais voir cet article.
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')
Utilisez le fichier de spécification réécrit pour générer à nouveau un fichier exécutable.
pipenv run pyinstaller foo.spec
Lorsque j'ai exécuté le binaire généré, cela a bien fonctionné comme ci-dessous.
C:\Users\username\PycharmProjects\foo_project>dist\foo\foo
bar: Hello!
hoge!
Sous le répertoire dist où se trouve le binaire, un sous-répertoire pour pykakasi est créé comme indiqué ci-dessous, et vous pouvez voir que le dictionnaire est copié.
C:\Users\username\PycharmProjects\foo_project>dir .\dist\foo\pykakasi\data
C:\Users\username\PycharmProjects\foo_project\dist\foo\pykakasi\répertoire de données
<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
C'est tout pour le post-scriptum.
Recommended Posts