PyQt5/PyInstaller 应用程序在 OSX 上无限循环地打开多个副本

Mit*_*tch 6 macos pyinstaller python-3.x pyqt5

我有一个 Python3/PyQT5 应用程序的奇怪问题,使用 PyInstaller 冻结。在 macOS 上,代码从 CLI 运行良好。使用 PyInstaller 冻结的版本也可以成功运行,但每隔几秒钟就会在看起来像无限循环的情况下创建自己的新副本。什么可能导致这种行为?

作为背景,我已经成功地在 Ubuntu 18.05 和 Windows 10 上冻结了这个应用程序,而没有看到这个问题。

我在 macOS Mojave 10.14.3 上运行带有 PyInstaller 3.4 和 PyQT5 5.12 的 Python 3.7.2。

鉴于 Python 代码从 CLI 和 PyCharm 完美运行,并且冻结包运行(但具有多个副本),看起来问题出在冻结过程中的某个地方。

我正在使用的 PyInstaller .spec 文件在这里:

# -*- mode: python -*-
import sys
import os
block_cipher = None

def get_assets():
    data_files = []
    for file_name in os.listdir('/Users/xxx/PycharmProjects/jbrd2/jbrd/assets'):
        data_files.append((os.path.join('jbrd/assets', file_name), 'assets'))
    data_files.append(('/Users/xxx/PycharmProjects/jbrd2/jbrd/jbrdclasses.py', '.'))
    data_files.append(('/Users/xxx/PycharmProjects/jbrd2/jbrd/assets/config.ini', 'assets'))
    data_files.append(('/Users/xxx/PycharmProjects/jbrd2/jbrd/python_mysql_connect2.py', '.'))
    data_files.append(('/Users/xxx/PycharmProjects/jbrd2/jbrd/python_mysql_dbconfig.py', '.'))
    return data_files

a = Analysis(['jbrd/main.py'],
             pathex=['/Users/xxx/PycharmProjects/jbrd2'],
             binaries=[],
             datas=get_assets(),
             hiddenimports=['sklearn.naive_bayes','simpleeval', 'configparser', 'mysql.connector'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='jbrd',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=False,
          icon='/jbrd.ico')

# Build a .app if on OS X
if sys.platform == 'darwin':
   app = BUNDLE(exe,
                name='jbrd.app',
                icon=None,
                bundle_identifier=None,
                info_plist={
                'NSHighResolutionCapable': 'True'
                },
                )
Run Code Online (Sandbox Code Playgroud)

我不知道什么可能导致应用程序运行自身的多个副本。请问有什么建议吗?

多亏了这里的一些帮助1我现在已经缩小了这个问题的原因。我可以确认运行 1 行脚本:

import sklearn

使用 PyInstaller 冻结会导致无限循环。向 PyInstaller .spec 文件添加排除项:

excludes=['sklearn.externals.joblib']

解决问题。潜在的问题是冻结调用 joblib 的应用程序会导致无限循环。您可以通过冻结 1 行脚本来证明这一点

import joblib

你会看到这会导致无限循环。我的应用程序不直接调用 joblib,而是使用 sklearn 中的机器学习功能。不幸的是,sklearn 调用 joblib,这就是导致我的应用程序在冻结时循环的原因。这似乎是 PyInstaller 中的一个错误。任何人都可以提出解决方法吗?