我正在尝试从
Scrapy
项目中生成可执行文件。我注意到我必须说 PyInstaller
它必须加载哪些 scrapy 模块。问题是这些模块有很多。
pyinstaller --onefile main.py --hidden-import scrapy.spiderloader --hidden-import scrapy.statscollectors --hidden-import scrapy.....
是否可以设置
PyInstaller
来预导入所有模块?像 --hidden-import scrapy.*
这样的东西不起作用。
讨论真的很晚,但刚刚遇到了同样的问题,这就是我最终找到的解决方案。
使用
.spec
文件生成可执行文件。 .spec
文件实际上被解释为 python 文件,您可以包含自己的代码来设置 PyInstaller 设置。
创建一个列出您所有
hiddenimports
的函数。对于我的用例,我使用了从项目中的文件夹动态导入,但您可以使用相同的想法和其他代码来列出您需要的所有模块。这就是我的 .spec
文件的样子:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
# Generate list of hidden imports
import os
def list_python_files(dir_name):
file_list = []
for filename in os.listdir(dir_name):
if filename.endswith('.py'):
file_list.append(f"{dir_name}.{filename[:-3]}")
return file_list
hiddenimports = list_python_files('folder_name_here')
a = Analysis(
['app.py'],
pathex=[],
binaries=[],
datas=[('icon.ico', '.')],
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
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,
[('v', None, 'OPTION')],
exclude_binaries=False, # changed to False
name='app',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='icon.ico',
)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='app',
)
2023 年解决方案详细介绍如下:https://github.com/pyinstaller/pyinstaller/issues/1905#issuecomment-525221546
基本上你需要创建一个合适的钩子。
确保挂钩从可执行文件内的插件文件夹中注入“隐藏”模块:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
# Generate list of hidden imports
import os
def list_python_files(dir_name):
file_list = []
for filename in os.listdir(dir_name):
if filename.endswith('.py'):
file_list.append(f"{dir_name}.{filename[:-3]}")
return file_list
hiddenimports = list_python_files('folder_name_here')
a = Analysis(
['app.py'],
pathex=[],
binaries=[],
datas=[('icon.ico', '.')],
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
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,
[('v', None, 'OPTION')],
exclude_binaries=False, # changed to False
name='app',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='icon.ico',
)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='app',
)
模块下myappname/pluginfolder
specs/hook-<myappname.pluginfolder>.py
Pyinstaller 应该创建一个“main.spec”文件。在该文件中,有一行包含“hiddenimports=[]”。您可以在此处列出所有隐藏的导入,并且只需执行一次。您也许可以在该列表中使用通配符,但我不确定。