2012-02-06 22 views
10

Tôi gặp sự cố khi phân phối ứng dụng sử dụng pytz. Tôi đang sử dụng Py2Exe để tạo tệp thực thi từ nguồn Python của tôi.UnknownTimezoneError Ngoại lệ được nâng lên với ứng dụng Python được biên dịch bằng Py2Exe

Đối với một ví dụ đơn giản của vấn đề tôi đang gặp, tôi có: pytz_test.py:

import pytz 

tz_au = pytz.timezone("Australia/Sydney") 
print tz_au 

và trong setup.py:

from distutils.core import setup 
import py2exe 

setup(console=['pytz_test.py'], options={"py2exe" : { 'packages': ['pytz'], } }) 

sau đó tôi chạy setup.py :

python setup.py py2exe 

Việc biên dịch tệp thực thi. Chạy tạo pytz_test.exe tôi nhận được:

Tôi cho rằng đó là bởi vì thông tin múi giờ là không nhận được đi kèm với các thực thi, nhưng tôi không chắc chắn làm thế nào để làm cho nó xảy ra.

EDIT: Một giải pháp đơn giản sẽ có thêm thư mục zoneinfo, từ pytz mô-đun trong python thư mục trang web-bì, đến library.zip.

Để làm điều này tự động, Tôi làm theo các giải pháp trong dự án mà Google Transit liệu thức ăn sử dụng, từ: http://code.google.com/p/googletransitdatafeed/source/browse/trunk/python/setup.py

My sửa đổi setup.py bây giờ trông giống như:

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() 
+0

Bạn cũng cần phiên bản hiện tại của công cụ thiết lập. Cụ thể pkg_resources. 'nhập pkg_resources' không được thất bại. – sbaechler

+0

Trường hợp sử dụng 'pkg_resources' chính xác ở đâu? hoặc chỉ bằng cách nhập nó? – Triztian

Trả lời

3

Một giải pháp đơn giản là thêm thư mục zoneinfo, từ mô-đun pytz vào gói trang web trăn thư mục, đến thư viện .zip.

Để làm điều này tự động, Tôi làm theo các giải pháp dự án Google Transit liệu thức ăn sử dụng, từ:

My sửa đổi setup.py bây giờ trông giống như:

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() 

(Được trả lời bởi người hỏi)

2

Việc nén vùng thông tin theo cách thủ công (như được mô tả bởi Jason S) đã giúp thực sự cho việc xây dựng g gói trên một trong các máy tính của tôi. Tuy nhiên, khi tôi xây dựng gói trên máy tính khác - lỗi đã xảy ra! Tìm lý do đã cho tôi một thời gian - vì vậy tôi nên chia sẻ tốt hơn.

Giải pháp được đề xuất không hoạt động với các phiên bản pytz mới (ít nhất là với 2014.7)! Đào tại sao điều này được tiết lộ rằng pytz đã thay đổi định dạng của các tệp zoneinfo từ pyc thành một số định dạng nhị phân.Với tôi nó trông giống như, với sự thay đổi này họ "phá vỡ" các tùy chọn để đóng gói pytz vào một zip, kể từ khi cơ chế zipimport xây dựng của python không hoạt động để tải các tập tin nhị phân. Trên thực tế, vấn đề này cần được cố định bởi pytz nhưng bây giờ tôi thấy một giải pháp:

  • Chỉ cần sao chép toàn bộ thư mục pytz trực tiếp vào thư mục của bạn, TP
  • trong chương trình của bạn, thêm đường dẫn của main- của bạn exectutable đến đường dẫn tìm kiếm python của

Thực tế, điều này có nghĩa trong bạn setup.py thay thế pytz-nén với

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')) 

và di chuyển pytz từ "gói" -option để "loại trừ":

options = { 
    "py2exe" : { 
     "compressed": 1, 
     "optimize": 2, 
     "packages": [], 
     "excludes": ['pytz'] 
    } 
} 

Tại mục chính của chương trình của bạn (để chắc chắn rằng nó được thực hiện trước khi nhập pytz), bạn sẽ phải thêm một cái gì đó như:

import os, sys 
basePath = os.path.dirname(os.path.abspath(sys.argv[0])) 
sys.path.insert(0, basePath) 
+0

Điều này làm việc cho tôi (pytz 2014.10), nhưng tôi đã phải loại bỏ tất cả bỏ qua từ shutil.copytree(). – Geotob

+0

Có! Nó đã làm việc! Điều kỳ lạ nhất là pytz của tôi với py2exe đang hoạt động. Sau đó, tôi sửa đổi một vài điều trong chương trình của tôi, hoàn toàn không liên quan đến pytz, và đột nhiên nó ngừng hoạt động và cung cấp cho các UnkownTimeZoneError – wordsforthewise

+0

wordsforthewise, chính xác! Đó cũng là vấn đề của tôi. Và kể từ khi (ít nhất là với tôi) nó không phải luôn luôn rõ ràng những gì py2exe nào và làm thế nào nó thu thập những thứ của nó, tôi thậm chí đã phải hack gỡ lỗi in vào pytz để tìm hiểu những gì đã đi sai trong giai đoạn thu thập py2exe của. :-) – Zappotek

Các vấn đề liên quan