如何解决找不到Pyinstaller模块错误

问题描述

我正在尝试使用Pyinstaller将我的项目打包为可执行文件。目前,我正在我的基于Ubuntu的PC上进行概念验证,之后我计划切换到Windows来构建一个可以在Windows上运行的.exe。问题是,在我构建可执行文件并运行它之后,它找不到在启动文件中导入的一个本地包。这是我的项目结构:

.
├── hook-streamlit.py
├── __init__.py
├── models
│   ├── __init__.py
│   ├── loader.py
│   ├── nn.py
│   └── runner.py
├── notebooks
├── README.md
├── requirements.txt
├── stapp
│   ├── __init__.py
│   ├── main.py
│   └── session_state.py
├── startup.py
├── startup.spec
├── test_data
│   ├── test_x.csv
│   ├── test_y.csv
│   ├── train_x.csv
│   └── train_y.csv
├── tkapp.py
├── unipredictor-icon.ico
├── UniPredictor.spec
└── utils.py

startup.py是启动脚本,内容如下:

import os
import subprocess
import shlex

from models import nn, loader, runner
from stapp import main

subprocess.call(shlex.split(f"streamlit run {os.path.join('stapp', 'main.py')} --global.developmentMode=false"))
尽管我不需要启动脚本中的modelsstapp包,但我导入它们只是为了确保pyinstaller解决依赖关系,因为我使用子进程来运行应用程序。但是,即使这样,在构建和运行可执行文件之后,我仍然得到ModuleNotFoundError: No module named 'models'。此错误来自导入modelsstapp.main。我已尝试将modelsstapp添加到hiddenimports,但未成功。我认为既然项目根目录被添加到PYTHONPATH中,它对于本地包应该不会有任何问题。即使出于某种原因,进口和隐藏进口也应该解决这一问题。以下是我当前的规范文件:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['startup.py'],
             pathex=['/home/kenneth/PycharmProjects/universal_predictor'],
             binaries=[],
             datas=[],
             hiddenimports=['models', 'stapp'],
             hookspath=['.'],
             runtime_hooks=[],
             excludes=['torch.distributions'],
             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='startup',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=False , icon='unipredictor-icon.ico')

我将感谢任何关于如何使pyinstaller包含项目的本地包的帮助。谢谢!


解决方案

我通过将所需的包和模块作为数据加载解决了此问题。

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['startup.py'],
             pathex=['/home/kenneth/PycharmProjects/universal_predictor'],
             binaries=[],
              datas=[('.streamlit', '.streamlit'), ('.data', '.data'), ('models', 'models'), ('stapp', 'stapp'), ('utils.py', '.')],
             hiddenimports=[],
             hookspath=['.'],
             runtime_hooks=[],
             excludes=['torch.distributions'],
             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='startup',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=False , icon='unipredictor-icon.ico')

相关文章