使用pytz库构建EXE时触发UnknownTimeZoneError问题求助
解决py2exe打包pytz脚本时的UnknownTimeZoneError问题
我之前也碰到过一模一样的问题!直接跑脚本完全正常,但用py2exe打包成EXE后就报UnknownTimeZoneError: 'Europe\Ljubljana',折腾了好久才发现根源:py2exe默认不会打包pytz的时区数据文件——这些数据不是Python代码,而是存放在pytz/zoneinfo目录下的二进制/文本文件,打包时被漏掉了,导致运行EXE时找不到对应时区。
下面是几个亲测有效的解决方案,按推荐程度排序:
方案1:修改setup.py,强制包含pytz时区数据
直接在setup.py里添加代码,把pytz/zoneinfo下的所有文件都打包进去。修改后的setup.py示例如下:
from distutils.core import setup import os.path import pytz try: import py2exe has_py2exe = True except ImportError as e: has_py2exe = False # 获取pytz库的zoneinfo目录绝对路径 pytz_zoneinfo_root = os.path.join(os.path.dirname(pytz.__file__), 'zoneinfo') # 遍历zoneinfo目录,收集所有需要打包的文件 zoneinfo_data_files = [] for root, _, files in os.walk(pytz_zoneinfo_root): if files: # 计算相对路径,保证打包后的目录结构和原库一致 relative_dir = os.path.relpath(root, pytz_zoneinfo_root) target_dir = os.path.join('pytz', 'zoneinfo', relative_dir) file_paths = [os.path.join(root, f) for f in files] zoneinfo_data_files.append((target_dir, file_paths)) # 替换成你的实际脚本文件名 myScript = "your_script.py" setup( # 如果是GUI程序,把console换成windows console=[myScript], data_files=zoneinfo_data_files, options={ "py2exe": { # 明确指定要包含pytz库 "packages": ["pytz"], "includes": ["pytz"] } } )
运行修改后的setup.py重新打包,时区数据就会被正确包含进去了。
方案2:在脚本中手动指定时区数据路径
如果不想修改setup.py,可以在你的业务脚本开头添加一段代码,当检测到是打包后的EXE时,手动告诉pytz时区数据的位置:
import pytz import os import sys # 判断是否是打包后的EXE环境 if hasattr(sys, 'frozen'): # 打包后,时区数据会在EXE同目录的pytz/zoneinfo下 zoneinfo_path = os.path.join(os.path.dirname(sys.executable), 'pytz', 'zoneinfo') # 手动加载时区数据 pytz.zoneinfo.ZoneInfoFile(zoneinfo_path)
注意这种方法需要确保你已经通过其他方式把pytz/zoneinfo目录复制到EXE的同目录下(比如手动复制,或者在setup.py里添加data_files)。
方案3:改用PyInstaller打包
py2exe对第三方库的资源文件支持确实不太友好,如果你愿意换打包工具,PyInstaller会省心很多——它默认会自动识别并打包pytz的时区数据。
安装PyInstaller后,直接运行命令打包:
pyinstaller --onefile your_script.py
如果偶尔还是出现时区问题,加上--collect-all pytz参数强制收集所有pytz的文件:
pyinstaller --onefile --collect-all pytz your_script.py
内容的提问来源于stack exchange,提问作者Sam_slo
相关产品推荐
相关产品推荐

