为什么 cx_Freeze 在 运行 一个 exe 文件时出现这个错误?

Why does cx_Freeze rise this error when running an exe file?

我是 cx_Freeze 的新用户,我想将我的 python 文件与所有需要的依赖项打包在一起。

我用Python3.

我在 python virtualenv 下工作,具有 tensorflow, sklearn, matplotlib, python-vlc...

等依赖项

这是在 Windows 上重现相同错误所需的所有文件。

我的requirements.txt要安装

absl-py==0.7.0
altgraph==0.16.1
astor==0.7.1
audioread==2.1.6
certifi==2018.11.29
chardet==3.0.4
cx-Freeze==5.1.1
cycler==0.10.0
decorator==4.3.2
distlib==0.2.8
future==0.17.1
gast==0.2.2
grpcio==1.18.0
h5py==2.9.0
idna==2.8
Jinja2==2.10
joblib==0.13.1
Keras-Applications==1.0.7
Keras-Preprocessing==1.0.9
kiwisolver==1.0.1
librosa==0.6.2
llvmlite==0.27.0
macholib==1.11
Markdown==3.0.1
MarkupSafe==1.1.0
matplotlib==3.0.2
numba==0.42.0
numpy==1.16.1
pefile==2018.8.8
protobuf==3.6.1
py2exe==0.9.2.2
PyInstaller==3.4
pynsist==2.3
pyparsing==2.3.1
pypiwin32==223
pysrt==1.1.1
python-dateutil==2.8.0
python-vlc==3.0.4106
pywin32==224
pywin32-ctypes==0.2.0
requests==2.21.0
requests-download==0.1.2
resampy==0.2.1
scikit-learn==0.20.2
scipy==1.2.0
six==1.12.0
sklearn==0.0
tensorboard==1.12.2
tensorflow==1.12.0
termcolor==1.1.0
tornado==5.1.1
urllib3==1.24.1
watson-developer-cloud==2.8.0
websocket-client==0.48.0
Werkzeug==0.14.1
yarg==0.1.9

我有一个主要的 python 文件 IHM.py 从另外两个 python 文件中导入模块 sync.pyneurnet.py.

文件ihm.py

# -*- coding: utf-8 -*-

# for Python3
from tkinter import *
import matplotlib.backends.backend_tkagg
import matplotlib.pyplot as mp
import tkinter.filedialog
from watson_developer_cloud import LanguageTranslatorV3
import json
import subprocess
import os
import vlc
from sync import *
import warnings

warnings.filterwarnings("ignore")

# Définition des variables globales
vid_file_path = ""
vid_srt_path = ""
vid_srt_path_trans = ""
vid_srt_path_sync = ""


# Création de la fenetre d'IHM
fenetre = Tk()
fenetre.title("Test Tkinter Windows")



fenetre.mainloop()

文件sync.py

# -*- coding: utf-8 -*-
from __future__ import division
from neuralNet import 

文件neurnet.py

#coding: utf-8
import os
import time
import sys
import librosa
import re
import io
import subprocess
import pysrt
import numpy as np
import matplotlib.pyplot as plt
from time import time
import tensorflow as tf
import pickle
#from sklearn.model_selection import train_test_split
#from tensorflow.contrib.layers import flatten
import sklearn



from subprocess import STDOUT

try:
    from subprocess import DEVNULL # py3k
except ImportError:
    import os
    DEVNULL = open(os.devnull, 'wb')

在这里,cx_Freeze setup.py :

# setup.py 
import sys, os
from cx_Freeze import setup, Executable

os.environ['TCL_LIBRARY'] = 'C:/Program Files/Python36/tcl/tcl8.6' 
os.environ['TK_LIBRARY'] = 'C:/Program Files/Python36/tcl/tk8.6'
__version__ = "1.1.0"

buildOptions = dict(
    packages = [],
    excludes = [],  includes = ["idna.idnadata"],
    include_files = ['C:/Program Files/Python36/DLLs/tcl86t.dll','C:/Program Files/Python36/DLLs/tk86t.dll'] )

import sys

base = 'Win32GUI' if sys.platform=='win32' else None 
executables = [
    Executable('ihm.py', base=base) 
] 
setup(
    name = "mgp320",
    description='Projet Neural Network Speech Detection',
    version=__version__,
    options = dict(build_exe = buildOptions),
    executables = executables
)

运行 此设置使用命令:python setup.py build 所以它为我创建了一个 exe 文件,但是当我 运行 这个 exe 时,我得到了这个错误 window :

Error cx_Freeze

引用如下:

Traceback (most recent call last):
 File
"C:\Users\achraf.bentabib\Desktop\aapsa\aapsa\env\lib\site-p
ackages\cx_Freeze\initscript\__startup__.py", line 14, in run
  module.run()
 File
"C:\Users\achraf.bentabib\Desktop\aapsa\aapsa\env\lib\site-p
ackages\cx_Freeze\initscript\Console.py", line 26, in run
  exec(code, m.__dict__)
 File "ihm.py", line 5, in <module>
 File
"C:\Users\achraf.bentabib\Desktop\aapsa\aapsa\env\lib\site-p
ackages\matplotlib\__init__.py", line 120, in <module>
   import distutils.version
 File
"C:\Users\achraf.bentabib\Desktop\aapsa\aapsa\env\lib\distut
ils\__init__.py", line 35, in <module>
   loader.exec_module(real_distutils)
 File "<frozen importlib._bootstrap_external>", line 674, in
exec_module
 File "<frozen importlib._bootstrap_external>", line 780, in
get_code
 File "<frozen importlib._bootstrap_external>", line 832, in
get_data
FileNotFoundError: [Errno 2] No such file or directory:
"C:\Users\achraf.bentabib\Desktop\aapsa\aapsa\stack\b
uild\exe.win-amd64-3.6\lib\library.zip\distutils\__init__.py'

我真的不知道该如何解决..

我在 cx_Freeze 5.1.1 的安装脚本中看到以下潜在问题:

  1. 您正在使用 numpy(和 matplotlib 取决于 numpy)。为了 cx_Freeze 正确冻结 numpy,需要将其添加到 build_exe 选项的 packages 列表中。

  2. 对于 cx_Freeze 版本 5.1.1,TCL/TK DLL 需要包含在构建目录的 lib 子目录中。您可以通过将元组 (source, destination) 传递给 include_files 列表选项的相应条目来实现。此外,动态找出 TCL/TK DLL 的位置会更安全。

总之,尝试在您的设置脚本中进行以下修改:

PYTHON_INSTALL_DIR = os.path.dirname(sys.executable)
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')

buildOptions = dict(
    packages = ["numpy"],
    excludes = [],
    includes = ["idna.idnadata"],
    include_files=[(os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'),
                    os.path.join('lib', 'tk86t.dll')),
                   (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'),
                    os.path.join('lib', 'tcl86t.dll'))]
)

如果此修改仍然不起作用,请从最小的 tkinter 应用程序开始,例如,在您发布的示例应用程序中注释掉所有导入但 tkinter 并使其工作在你的系统上。然后逐一重新添加您需要的模块(numpymatplotlib、...)并检查解冻和冻结的应用程序是否在每一步都正常工作。例如,您可以向示例应用程序添加一个消息框,并在那里打印您导入的每个模块的版本。

我终于找到了最后一个回溯的解决方案:

from distutils import dist, sysconfig # isort:skip 
ImportError: cannot import name "dist" 

问题是 distutils 没有很多模块没有安装在 virtualenv 中。 (仅 __init__.py) 所以当我们构建 exe 时,它​​没有找到 distutils 模块...

要解决这个问题,我们必须手动导入 disutils

import distutils
import opcode
import os
distutils_path = os.path.join(os.path.dirname(opcode.__file__), 'distutils')

然后,将此路径包含到 cx_freeze 的 include_files 选项中,然后 在排除部分排除 distutils。

buildOptions = dict(
    packages = ['llvmlite', 'pkg_resources._vendor', "tkinter", 'numba', "tkinter.filedialog", "audioread", "librosa", "scipy", "numpy"],
    excludes = ["scipy.spatial.cKDTree", 'distutils'],
    includes = ["idna.idnadata", 'numpy.core._methods', 'numpy.lib.format', 'matplotlib.backends.backend_tkagg'],
    include_files = [(distutils_path, 'distutils'), 'C:/Program Files/Python36/DLLs/tcl86t.dll','C:/Program Files/Python36/DLLs/tk86t.dll']
)

我还在包中添加了 pkg_resources._vendor,因为没有这个,cx_freeze 会引发错误,例如

ImportError: The 'appdirs' package is required; normally this is bundled with th
is package so if you get this warning, consult the packager of your distribution

终于成功了,我将 numba 添加到包含的包中,因为与 disutils 一样,构建不会创建所有必需的模块(对于 librosa)。

最后一个问题是关于 multiprocessing 库的。 我必须在构建库文件夹中手动将 Pool.pyc 重命名为 pool.pyc。