BPL*_*BPL 19 python pyinstaller python-3.x
我试图弄清楚如何使用PyInstaller加载动态/隐藏导入,到目前为止我得到了这个简单的结构:
首先,我在我的PYTHONPATH中添加了一个框架包 d:\Sources\personal\python\framework
我的许多python项目都使用了这个包,特别是它与我想要打包的下面简单项目一起使用
Main project
????data <- Pure static data
????plugins <- Dynamic modules which uses framework's modules
????resources <- Static data+embedded (generated by pyqt), used by plugins
? ????css
? ????images
| resources.py
| resources.qrc
main.py <- Uses framework's modules to load plugins dynamically
Run Code Online (Sandbox Code Playgroud)
我的spec文件看起来像这样:
# -*- mode: python -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=['d:\\sources\\personal\\python\\pyqt\\pyshaders'],
binaries=None,
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
##### include mydir in distribution #######
def extra_datas(mydir):
def rec_glob(p, files):
import os
import glob
for d in glob.glob(p):
if os.path.isfile(d):
files.append(d)
rec_glob("%s/*" % d, files)
files = []
rec_glob("%s/*" % mydir, files)
extra_datas = []
for f in files:
extra_datas.append((f, f, 'DATA'))
return extra_datas
###########################################
a.datas += extra_datas('data')
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='main',
debug=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='main')
Run Code Online (Sandbox Code Playgroud)
当我尝试将隐藏的导入添加到Analysis(...,hiddenimports = [],...)的hiddenimports列表时出现问题,到目前为止我已尝试过:
hiddenimports=['d:\\sources\\personal\\python\\pyqt\\plugins']hiddenimports=['d:\\sources\\personal\\python\\pyqt\\plugins\\*']hiddenimports=['plugins']还尝试列出具有绝对路径的单个文件:
hiddenimports=[
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\api.py',
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\config.py',
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\plugins_actions.py',
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\plugins_dialogs.py',
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\plugins_docks.py',
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\plugins_post_init.py',
'd:\\sources\\personal\\python\\pyqt\\pyshaders\\plugins\\plugins_toolbar.py'
]
Run Code Online (Sandbox Code Playgroud)
并尝试将它们作为模块包加载(__init__.py位于plugins文件夹中)
hiddenimports=[
'plugins.api',
'plugins.config',
'plugins.plugins_actions',
'plugins.plugins_dialogs',
'plugins.plugins_docks',
'plugins.plugins_post_init',
'plugins.plugins_toolbar'
]
Run Code Online (Sandbox Code Playgroud)
还尝试了collect_submodules
hiddenimports=collect_submodules('plugins')
Run Code Online (Sandbox Code Playgroud)
没有这些尝试工作,文件夹插件没有正确添加到dist(当我说'正确'我猜pyinstaller将分析这些隐藏插件使用的导入递归分析他们的依赖和复制*.pyc文件). ..所以,我想知道如何添加正确加载到pyinstaller规范的"隐藏"模块.
我在使用 Py2Exe 打包 PyQt 应用程序时遇到了类似的问题(我也在 PyInstaller 和 cx_freeze 上遇到了困难,但只有 py2exe 帮助了我)。
这是详细的解决方案。我已将它们明确添加为:
data_files += [('source', glob('source/*.py'),)]
setup(
data_files=data_files,
.... # other options
windows=[
{
"script": "launcher.py",
"icon_resources": [(0, "resources/favicon.ico")]
}
)
Run Code Online (Sandbox Code Playgroud)
然后我导入它们并调用。希望这个方法会有用。