Я сделал программу, которая отлично работала, и теперь я попытался скомпилировать ее с помощью cx_Freeze, но получил TypeError: можно только конкатенацию списка (а не "NoneType") для отображения ошибки. Итак, как я могу исправить эту проблему, чтобы я мог правильно скомпилировать свою программу.exe
Моя конфигурация: python 2.7, cx_Freeze 5.1.1
Моя программа содержит следующие модули: os, time, string, random, smtplib, _winreg, запросы, pyautogui, подпроцесс, электронная почта, SimpleCV
Код моего установочного файла:
import sys
from cx_Freeze import setup, Executable
company_name = 'My own company'
product_name = 'Program'
sys.setrecursionlimit(5000)
bdist_msi_options = {
'add_to_path': False,
'initial_target_dir': r'[C:\Program Files (x86)]\%s\%s' % (company_name, product_name),
}
path = sys.path
build_exe_options = {
"path": path,
"icon": "myicon.ico"}
base = None
if sys.platform == "win32":
base = "Win32GUI"
exe = Executable(script='My_program.py',
base=base,
icon='myicon.ico',
)
setup(name = "My program",
version = "1.1",
description = "This is my first program",
executables = [exe],
options = {'bdist_msi': bdist_msi_options})
Ошибка:
Traceback (most recent call last):
File "setup.py", line 33, in <module>
options = {'bdist_msi': bdist_msi_options})
File "C:\Python27\lib\site-packages\cx_Freeze\dist.py", line 349, in setup
distutils.core.setup(**attrs)
File "C:\Python27\lib\distutils\core.py", line 151, in setup
dist.run_commands()
File "C:\Python27\lib\distutils\dist.py", line 953, in run_commands
self.run_command(cmd)
File "C:\Python27\lib\distutils\dist.py", line 972, in run_command
cmd_obj.run()
File "C:\Python27\lib\distutils\command\build.py", line 127, in run
self.run_command(cmd_name)
File "C:\Python27\lib\distutils\cmd.py", line 326, in run_command
self.distribution.run_command(command)
File "C:\Python27\lib\distutils\dist.py", line 972, in run_command
cmd_obj.run()
File "C:\Python27\lib\site-packages\cx_Freeze\dist.py", line 219, in run
freezer.Freeze()
File "C:\Python27\lib\site-packages\cx_Freeze\freezer.py", line 623, in Freeze
self._WriteModules(fileName, self.finder)
File "C:\Python27\lib\site-packages\cx_Freeze\freezer.py", line 600, in _WriteModules
path = os.pathsep.join([origPath] + module.parent.path)
TypeError: can only concatenate list (not "NoneType") to list
Решение размещает файл opencv_ffmpeg342.dll в том же каталоге, где находится исполняемый файл.
opencv_ffmpeg342.dll находится в [ Место, где вы установили python ] \ Lib\site-packages\cv2
include-files: ['[Place where you have installed python]/Lib/site-packages/cv2/opencv_ffmpeg342.dll']
к параметрам build_exe
в сценарии установки.
Модуль cv2
вызывает бесконечную рекурсию cx_Freeze
, см. Совместимость cx_Freeze - opencv
Удалить выражение
sys.setrecursionlimit(5000)
из вашего сценария установки. Затем вы должны увидеть следующую ошибку
module = self._modules[name] = Module(name)
RuntimeError: maximum recursion depth exceeded while calling a Python object
Если вы можете жить без использования cv2
, вы можете исключить его (см. Ниже, как это сделать).
Я предполагаю, что еще одна проблема может заключаться в том, что SimpleCV требует numpy и scipy, и эти пакеты должны быть включены явно в скрипт установки cx_Freeze.
В целом, попробуйте изменить свои build_exe_options
следующим образом:
build_exe_options = {"path": path,
"include_files": ["myicon.ico"],
"packages": ["numpy", "scipy"],
"excludes": ["scipy.spatial.cKDTree", "cv2"]}
Параметр path
фактически не нужен, поскольку значением по умолчанию является sys.path
.
Опция icon
не существует, я думаю, вы намеревались использовать include_files
. Этот параметр может не понадобиться, если вы не используете файл значка в самой программе.
Не забудьте добавить команду build_exe_options
в команду setup
:
setup(name = "My program",
version = "1.1",
description = "This is my first program",
executables = [exe],
options = {'build_exe': build_exe_options,
'bdist_msi': bdist_msi_options})
На моей машине Linux я все еще получаю ошибки, вызванные matplotlib
после этих изменений (см. Cx_freeze error с данными matplotlib), но они кажутся специфичными для Linux, поэтому в Windows это может сработать для вас.