2014年4月11日 星期五

如何讓自己的python模組在python2和python3環境下皆可執行

考慮以下的情境:
  • 您有兩個projects,使用python語言,簡稱為PA與PB
  • PA用到別人的舊module(非用不可),用python2.7的語法,所以您使用python2.7 (M1)
  • PB用到別人的新module(非用不可),用python3的語法,所以您使用python3 (M2)
  • 兩個projects有共用的程式碼,您當然將它們抽出來,寫成您自己的module (M3)
因為python3和python2之間,有語法不同的差異,也有module名稱改變的差異,所以您的M3要寫成同時在PA和PB都能使用才行。當然拆成兩份也是可以,不過往後的管理維護上比較麻煩。

  • 化解print function和字串編碼原則的不一致
    • 在python3中,字串統一是使用unicode來儲存;在python2中則是有彈性,但是這個彈性會造成您的module要時時留意編碼問題。在使用python2的大型程式開發,其實就有公司採取「一律先轉成unicode再處理」的原則。
    • 處理方法:在程式碼開頭輸入以下,就可以使用python3的print與字串編碼原則(在使用python3時,該行不會有錯誤)
from __future__ import print_function, unicode_literals 

  • 一般性的處理
    • 在import sys之後,程式碼可以使用sys.version_info取得python的版本。如果只需要分辨python2.x與python3.x,大致上可以這麼作(臨場應變):
if sys.version_info.major == 2:
# codes for python2
elif sys.version_info.major == 3:
# codes for python3

以開utf-8檔為例,只需要 python2 的部份就好了(臨場應變,讓程式碼簡潔):
from __future__ import print_function, unicode_literals
import sys
if sys.version_info.major == 2:
    import codecs
    open = codecs.open

# ....
# 之後可以這麼用

with open(f_name, 'r', encoding='utf-8') as f_in:
    for line in f_in:
        print(line)

沒有留言:

張貼留言