You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyInstaller打包Python程序导入exchangelib报zoneinfo属性缺失错误

PyInstaller打包exchangelib依赖导入失败问题

问题背景

开发可定时连接Exchange Server向收件人发送邮件的Python应用,程序运行依赖exchangelib库:

  • 直接运行.py源文件时,无论通过命令行还是Jupyter Notebook启动,均可正常导入exchangelib及全部所需组件,运行无异常
  • 使用PyInstaller将程序打包为exe可执行文件后运行,触发导入失败报错

测试复现代码

print("Attempting: import exchangelib")
try:
    import exchangelib
    print("SUCCESS: import exchangelib")
except Exception as expOutput:
    print("FAILED: import exchangelib")
    print(expOutput)

print("Attempting: from exchangelib import DELEGATE, Account, Credentials, Configuration, Message, Mailbox, FileAttachment, HTMLBody")
try:
    from exchangelib import DELEGATE, Account, Credentials, Configuration, Message, Mailbox, FileAttachment, HTMLBody
    print("SUCCESS: import DELEGATE, Account, Credentials, Configuration, Message, Mailbox, FileAttachment, HTMLBody")
except Exception as expNewOutput:
    print(expNewOutput)

运行结果对比

直接运行py文件的正常输出

"SUCCESS: import exchangelib"
"SUCCESS: import DELEGATE, Account, Credentials, Configuration, Message, Mailbox, FileAttachment, HTMLBody"

打包为exe后的报错输出

Attempting: import exchangelib
FAILED: import exchangelib
module 'zoneinfo' has no attribute 'ZoneInfoNotFoundError'
Attempting: from exchangelib import DELEGATE, Account, Credentials, Configuration, Message, Mailbox, FileAttachment, HTMLBody
module 'zoneinfo' has no attribute 'ZoneInfoNotFoundError'

原使用的打包命令

C:\>cd C:\Users\aguler\AppData\Roaming\Python\Python37

C:\Users\aguler\AppData\Roaming\Python\Python37>ProjectEnvironment\Scripts\activate.bat

(ProjectEnvironment) C:\Users\aguler\AppData\Roaming\Python\Python37>Scripts\pyinstaller --onefile C:\PyFiles\Email_Troubleshoot\Test_exchangelib.py --paths=C:\Users\aguler\AppData\Roaming\Python\Python37\site-packages\tzdata --paths=C:\Users\aguler\AppData\Roaming\Python\Python37\site-packages\tzdata\zoneinfo --paths=C:\users\aguler\appdata\roaming\python\python37\projectenvironment\lib\site-packages\exchangelib --paths=C:\Users\aguler\AppData\Roaming\Python\Python37\ProjectEnvironment\Lib\site-packages\backports

问题根因

Python3.7无内置zoneinfo模块,exchangelib通过backports.zoneinfo回退包调用时区相关能力;原打包命令中手动添加的多个--paths参数直接指向依赖的子目录,打乱了模块导入层级,且PyInstaller默认无法自动识别backports这类命名空间包的动态导入逻辑,未将完整的backports.zoneinfo相关依赖打包进exe,导致运行时找不到ZoneInfoNotFoundError属性。

解决步骤

  1. 先删除之前打包生成的build、dist文件夹,以及同目录下生成的.spec打包配置文件,避免旧配置干扰
  2. 移除原打包命令中所有指向依赖子目录的--paths参数,这类参数仅用于添加Python模块搜索的根目录,指向子目录会破坏模块导入的层级关系
  3. 调整打包命令,显式声明需要收集的隐藏依赖与时区数据,修改后的命令如下(虚拟环境激活状态下执行):
pyinstaller --onefile C:\PyFiles\Email_Troubleshoot\Test_exchangelib.py ^
--hidden-import backports.zoneinfo ^
--hidden-import backports.zoneinfo._common ^
--hidden-import backports.zoneinfo._zoneinfo ^
--collect-all backports.zoneinfo ^
--collect-all tzdata
  1. 若执行上述命令后仍存在导入报错,可在测试代码的最顶部(所有exchangelib相关导入之前)添加一行显式导入,强制PyInstaller识别依赖:
from backports.zoneinfo import ZoneInfoNotFoundError

注意:打包完成后可先在命令行中启动生成的exe,确认输出两个SUCCESS提示即为修复完成。

内容的提问来源于stack exchange,提问作者AGuler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:45:41