經(jīng)歷移植jinja2到python3的痛苦之后,我把項目暫時放一放,因為我怕打破python3的兼容。我的做法是只用一個python2的代碼庫,然后在安裝的時候用2to3工具翻譯成python3。不幸的是哪怕一點點的改動都會打破迭代開發(fā)。如果你選對了python的版本,你可以專心做事,幸運的避免了這個問題。
來自MoinMoin項目的Thomas Waldmann通過我的python-modernize跑jinja2,并且統(tǒng)一了代碼庫,能同時跑python2,6,2,7和3.3。只需小小清理,我們的代碼就很清晰,還能跑在所有的python版本上,并且看起來和普通的python代碼并無區(qū)別。
受到他的啟發(fā),我一遍又一遍的閱讀代碼,并開始合并其他代碼來享受統(tǒng)一的代碼庫帶給我的快感。
下面我分享一些小竅門,可以達到和我類似的體驗。
放棄python 2.5 3.1和3.2
這是最重要的一點,放棄2.5比較容易,因為現(xiàn)在基本沒人用了,放棄3.1和3.2也沒太大問題,應為目前python3用的人實在是少得可憐。但是你為什么放棄這幾個版本呢?答案就是2.6和3.3有很多交叉哦語法和特性,代碼可以兼容這兩個版本。
字符串兼容。2.6和3.3支持相同的字符串語法。你可以用 "foo" 表示原生字符串(2.x表示byte,3.x表示unicode),u"foo" 表示unicode字符串,b"foo" 表示原生字符串或字節(jié)數(shù)組。 print函數(shù)兼容,如果你的print語句比較少,那你可以加上"from __future__ import print_function",然后開始使用print函數(shù),而不是把它綁定到別的變量上,進而避免詭異的麻煩。 兼容的異常語法。Python 2.6引入的 "except Exception as e" 語法也是3.x的異常捕捉語法。 類修飾器都有效。這個可以用在修改接口而不在類結(jié)構(gòu)定義中留下痕跡。例如可以修改迭代方法名字,也就是把 next 改成 __next__ 或者把 __str__ 改成 __unicode__ 來兼容python 2.x。 內(nèi)置next調(diào)用__next__或next。這點很有用,因為他們和直接調(diào)用方法的速度差不多,所以你不用考慮得太多而去加入運行時檢查和包裝一個函數(shù)。 Python 2.6 加入了和python 3.3接口一樣的bytearray類型。這點也很有用,因為2.6沒有 3.3的byteobject類型,雖然有一個內(nèi)建的名字但那僅僅只是str的別名,并且使用習慣也有很大差異。 Python 3.3又加入了byte到byte和string到string的編碼與解碼,這已經(jīng)在3.1和3.2中去掉了,很不幸,他們的接口很復雜了,別名也沒了,但至少更比以前的2.x版本更接近了。最后一點在流編碼和解碼的時候很有用,這功能在3.0的時候去掉了,直到3.3才恢復。
沒錯,six模塊可以讓你走得遠一點,但是不要低估了代碼工整度的意義。在Python3移植過程中,我?guī)缀鯇inja2失去了興趣,因為代碼開始虐我。就算能統(tǒng)一代碼庫,但還是看起來很不舒服,影響視覺(six.b('foo')和six.u('foo')到處飛)還會因為用2to3迭代開發(fā)帶來不必要的麻煩。不用去處理這些麻煩,回到編碼的快樂享受中吧。jinja2現(xiàn)在的代碼非常清晰,你也不用當心python2和3的兼容問題,不過還是有一些地方使用了這樣的語句:if PY2:。
新聞熱點
疑難解答
圖片精選