2011年5月14日 星期六

解決Python 跨平台相容性問題 (Mac OS X)

最近因工作需要使用Python來寫技術支援的程式,且其能在Tiger(10.4+), Leopard(10.5.5+), Snowlepoard (10.6.2+)正確執行。


測試開發用環境
Snowleopard 10.6.7 內建  python 2.6.1,
Leopard 10.5.8 內建 python 2.5.1
Tiger 10.4.8 內建 python 2.3.5

開發過程中,遇到下列問題:
Exception處理
try:

    open("/var/log/testexcept.log", w)
except IOError as (errno, strerror):
    print "Error %d: %s" % (errno, strerror)

上列程式,在Leopard 發生Exception錯誤。
$ python except_invalid.py
except_invalid.py:4: Warning: 'as' will become a reserved keyword in Python 2.6
  File "except_invalid.py", line 4
    except IOError as (errno, strerror):
                    ^
SyntaxError: invalid syntax
就Mac OS X 平台來說,"as" 是Python 2.6的保留字

解決方案:
try:
    open("/var/log/test.log", 'w')
except IOError, v:
    try:
       (code, msg) = v
    except:
       code = 0
       msg
    print "I/O Error:%d %s" % (code , msg)

執行結果:
$ python except_ok.py
I/O Error:13 Permission denied

readPlist/writePlist 不支援10.4


查了一下python plistlib 函式 python 2.5.1 and 2.6.1 都有相關函式
Python 2.5.1 (r251:54863, Jun 17 2009, 20:37:34)     ==>
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import plistlib
>>> dir(plistlib)
['Data', 'Dict', 'DumbXMLWriter', 'PLISTHEADER', 'Plist', 'PlistParser', 'PlistWriter', 'StringIO', '_InternalDict', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '_controlCharPat', '_dateFromString', '_dateParser', '_dateToString', '_encodeBase64', '_escapeAndEncode', 'binascii', 'datetime', 're', 'readPlist', 'readPlistFromResource', 'readPlistFromString', 'writePlist', 'writePlistToResource', 'writePlistToString']

python 2.3.5 沒有所需函式
Python 2.3.5 (#1, Jul 25 2006, 00:38:48)
[GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import plistlib
>>> dir(plistlib)
['Data', 'Date', 'Dict', 'DumbXMLWriter', 'False', 'INDENT', 'PLISTHEADER', 'Plist', 'PlistParser', 'PlistWriter', 'True', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '_encode', 'bool', 'sys']

解決方案:

使用Plist()的函式 fromFile(file) and write(file)
import plistlib
pl = plistlib.Plist()
file="/Applications/iTunes.app/Contents/version.plist"
dict = pl.fromFile(file)
print dict['CFBundleShortVersionString']
dict['CFBundleShortVersionString'] = "10.1"
dict.write("my.plist")

沒有留言: