如何使用PyInstaller打包导入zerorpc的Python脚本?
解决PyInstaller打包zerorpc脚本的ImportError问题
从你的错误日志和打包日志来看,问题出在PyInstaller默认的ZeroMQ钩子上——它自动排除了zmq.libzmq的导入(日志里的Excluding import 'zmq.libzmq'),但zerorpc依赖的zmq cython模块需要这个底层的C扩展库,导致运行时找不到_zmq_errno符号。
以下是具体的解决步骤:
方法1:修改spec文件(推荐)
首先找到你的ZeroMQ动态库路径:
打开终端运行以下命令,找到zmq的安装目录:python -c "import zmq; print(zmq.__path__)"进入该路径下的
libs文件夹,你会看到类似libzmq.5.dylib的文件(Mac系统),记下它的完整路径,比如/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/zmq/libs/libzmq.5.dylib。修改你的
api.spec文件:- 在
binaries参数中添加找到的动态库,指定打包后存放的路径为zmq/libs - 在
hiddenimports中添加zmq.libzmq,手动强制PyInstaller包含这个模块
- 在
修改后的spec文件如下:
# -*- mode: python -*- block_cipher = None a = Analysis(['api.py'], pathex=['/Users/username_test/Desktop/test/electron-python-example/pycalc/api_test'], binaries=[('/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/zmq/libs/libzmq.5.dylib', 'zmq/libs')], datas=[], hiddenimports=['zmq.libzmq'], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name='api', debug=False, strip=False, upx=True, runtime_tmpdir=None, console=True )
- 使用修改后的spec文件重新打包:
pyinstaller api.spec -F
方法2:直接用命令行参数打包
如果不想修改spec文件,可以直接在打包命令中添加必要的参数:
pyinstaller api.py -F --hidden-import zmq.libzmq --add-binary "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/zmq/libs/libzmq.5.dylib:zmq/libs"
原理说明
PyInstaller的默认hook-zmq.py钩子为了避免某些兼容性问题,会排除zmq.libzmq的导入,但zerorpc依赖的zmq cython后端需要这个底层库来提供_zmq_errno等核心符号。通过手动添加hidden import和对应的动态库,就能让打包后的程序在运行时找到所需的依赖。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

