PyInstaller打包Python程序触发os无属性循环导入报错
故障根因
该报错不是普通业务代码的循环导入问题,本质是自定义脚本与Python标准库模块重名引发的导入优先级冲突:
- PyInstaller打包时会自动把脚本所在目录(本次为
/root/BUILD)加入Python模块搜索路径,Python导入模块时会优先检索该路径下的文件 - Python标准库的
os模块初始化过程中,必须依赖内置的stat模块(对应报错日志里/usr/lib/python3.9/os.py第27行的import stat as st逻辑) - 你的打包入口脚本恰好命名为
/root/BUILD/stat.py,直接顶替了标准库的stat模块被优先加载 - 自定义的
stat.py中又引入了smtplib、socket等依赖,这些依赖初始化时需要调用尚未完成加载的os模块内部方法,最终抛出了“部分初始化模块无对应属性”的类循环导入报错。之前打包能正常运行,就是因为当时没有使用和标准库重名的脚本文件名。
修复步骤
- 将自定义的入口脚本
/root/BUILD/stat.py重命名为不与标准库冲突的名称,比如host_stat.py、monitor_stat.py均可,禁止使用stat.py作为Python脚本文件名 - 清理同目录下的缓存文件:删除
stat.pyc文件、__pycache__目录下所有和stat相关的缓存 - 删除之前打包生成的
stat.spec文件、build、dist输出目录,重新执行PyInstaller打包命令即可正常完成构建。
逻辑校验
可以顺着报错调用栈直接验证冲突链路:
Python解释器初始化 -> 加载site模块 -> 导入os模块 -> os尝试导入标准库stat -> 优先命中工作目录下自定义的stat.py -> 自定义stat.py加载smtplib依赖 -> smtplib加载socket依赖 -> socket尝试调用还未完成初始化的os模块内部方法
_get_exports_list-> 触发属性报错
内容的提问来源于stack exchange,提问作者user17658201
相关产品推荐
相关产品推荐

