我在分发使用pytz的应用程序时遇到了问题。我正在使用Py2Exe从我的Python源代码创建一个可执行文件。
关于我遇到的问题的一个简单例子,我有: pytz_test.py:
import pytz
tz_au = pytz.timezone("Australia/Sydney")
print tz_au在setup.py中:
from distutils.core import setup
import py2exe
setup(console=['pytz_test.py'], options={"py2exe" : { 'packages': ['pytz'], } })然后运行setup.py:
python setup.py py2exe它编译可执行文件。运行我得到的创建的pytz_test.exe:
Traceback (most recent call last):
File "pytz_test.py", line 3, in <module>
tz_au = pytz.timezone("Australia/Sydney")
File "pytz\__init__.pyc", line 185, in timezone
pytz.exceptions.UnknownTimeZoneError: 'Australia/Sydney'我认为这是因为时区信息没有与可执行文件捆绑在一起,但我不知道如何实现。
编辑:一个简单的解决方案是将zoneinfo目录从python packages目录中的pytz模块添加到library.zip中。
为了自动完成这一任务,我遵循了项目中的解决方案,该项目来自:http://code.google.com/p/googletransitdatafeed/source/browse/trunk/python/setup.py
我修改的setup.py现在看起来如下:
from distutils.core import setup
import glob
import py2exe
options = {
"py2exe" : {
"compressed": 1,
"optimize": 2,
'packages': ['pytz'],
}
}
setup(console=['pytz_test.py'], options=options)
import pytz
import os
import zipfile
zipfile_path = os.path.join("dist/" 'library.zip')
z = zipfile.ZipFile(zipfile_path, 'a')
zoneinfo_dir = os.path.join(os.path.dirname(pytz.__file__), 'zoneinfo')
disk_basedir = os.path.dirname(os.path.dirname(pytz.__file__))
for absdir, directories, filenames in os.walk(zoneinfo_dir):
assert absdir.startswith(disk_basedir), (absdir, disk_basedir)
zip_dir = absdir[len(disk_basedir):]
for f in filenames:
z.write(os.path.join(absdir, f), os.path.join(zip_dir, f))
z.close()发布于 2014-08-02 18:05:33
一个简单的解决方案是将zoneinfo目录从python packages目录中的pytz模块添加到library.zip中。
为了自动做到这一点,我遵循了项目所使用的解决方案,来自:http://code.google.com/p/googletransitdatafeed/source/browse/trunk/python/setup.py
我修改的setup.py现在看起来如下:
from distutils.core import setup
import glob
import py2exe
options = {
"py2exe" : {
"compressed": 1,
"optimize": 2,
'packages': ['pytz'],
}
}
setup(console=['pytz_test.py'], options=options)
import pytz
import os
import zipfile
zipfile_path = os.path.join("dist/" 'library.zip')
z = zipfile.ZipFile(zipfile_path, 'a')
zoneinfo_dir = os.path.join(os.path.dirname(pytz.__file__), 'zoneinfo')
disk_basedir = os.path.dirname(os.path.dirname(pytz.__file__))
for absdir, directories, filenames in os.walk(zoneinfo_dir):
assert absdir.startswith(disk_basedir), (absdir, disk_basedir)
zip_dir = absdir[len(disk_basedir):]
for f in filenames:
z.write(os.path.join(absdir, f), os.path.join(zip_dir, f))
z.close()(由提问者回答)
发布于 2014-10-27 13:18:33
手动压缩zoneinfo (如Jason所述)确实有助于在我的一台计算机上构建包。但是,当我在另一台计算机上构建这个包时,错误又回来了!找到原因花了我一段时间,所以我最好和大家分享一下。
建议的解决方案不适用于新的pytz版本(至少2014.7版本)!深入挖掘为什么会发现pytz将zoneinfo文件的格式从pyc更改为某种二进制格式。在我看来,通过这种修改,他们“破坏了”将pytz打包到zip中的选项,因为python的内置zipimport机制无法加载二进制文件。实际上,这个问题应该由pytz来解决,但现在我找到了另一个解决方案:
只需将整个pytz目录直接复制到dist directory
中即可。
实际上,这意味着在setup.py中将pytz- with替换为
import pytz, os, shutil
srcDir = os.path.dirname( pytz.__file__ )
dstDir = os.path.join( 'dist', 'pytz' )
shutil.copytree( srcDir, dstDir, ignore = shutil.ignore_patterns('*.py') )并将pytz从“包”-option移到“排除”:
options = {
"py2exe" : {
"compressed": 1,
"optimize": 2,
"packages": [],
"excludes": ['pytz']
}
}在程序的主条目(为了确保在导入pytz之前执行它),您必须添加如下内容:
import os, sys
basePath = os.path.dirname( os.path.abspath( sys.argv[0] ) )
sys.path.insert( 0, basePath )https://stackoverflow.com/questions/9158846
复制相似问题