隨著終止支援 Python 2 的腳步越來越近(至2020年),為了相容 Python 2 和 Python 3,許多 Python 包的開發者會使用下面的程式碼:
1 2 3 4 |
if sys.version_info[0] == 2: # Python 2 code else: # Python 3 code |
在某些方面,Python2 和 Python3 是存在差異的。
six 通過提供一層包裝,簡化了差異,使得程式碼在 Python 2 和 Python 3 中可以有相同的行為。舉一個例子,通常遍歷字典的 key
一般這樣做:
1 2 |
for item in dictionary.iteritems(): # code here |
在 Python2 中:
1 2 |
for item in dictionary.items(): # code here |
在 Python 3 中,使用 six
:
1 2 3 4 |
import six for item in six.iteritems(dictionary): # code here |
這種方法在 Python 2 和 Python 3 中可以無縫執行。但是,一些比較複雜的情況如本文開篇展示的例子,就需要藉助 if
來實現。同樣地,six
通過提供 PY2
和 PY3
兩個布林常量來簡化操作。
1 2 3 4 |
if six.PY2: # Python 2 code else: # Python 3 code |
這種方法目前為止還不錯。
這就引出了本文的主題,我們確實不知道 Python 4 將會是什麼樣子,但我們可以肯定的是,從 Python 3 向 Python 4 過渡會很流暢,不會像 Python3 一樣無法向後相容,如果是這樣的話,我們就可以無縫地使用為 Python 2 和 Python3 開發的工具包了。
但是情況並非完全如此。通過在 Github 上搜尋,匹配到了大約 300,000個結果,使用了下面這種語法:
1 2 3 4 |
if six.PY3: # Python 3 code else: # Python 2 code |
發現問題了嗎?在 six
中,PY3
是這樣定義的:
1 |
PY3 = sys.version_info[0] == 3 |
所以,一旦 Python 4 開始應用,PY2
和 PY3
的值將會為 False。
對於 Python 2 ,上述的 if
判斷中都將執行 else
。
下面再看一個有問題的程式碼:
1 2 3 4 |
if six.PY2: # Python 2 code elif six.PY3: # Python 3 code |
在這種情況下,Python 4 中將不會執行任何程式碼!
為了避免出現這個問題,關鍵在於我們應該避免在上述 if
宣告判斷時把 Python 3 當做特例,而是將 Python 2 當做特例,Python 3 作為預設條件:
1 2 3 4 |
if six.PY2: # Python 2 code else: # Python 3 code |
這是一個小改動,但會在以後省去很多讓人頭疼的問題。所以,如果你在開發 Python 包,檢查下你的程式碼以確保相容 Python 4。
更新:當然,不使用 six
,也能實現相同的邏輯。如果通過 sys.version_info
進行版本比較,確保不要這樣用:
1 2 3 4 |
if sys.version_info[0] == 3: # Python 3 code else: # Python 2 code |
檢查 Python 2 版本的程式碼時,要麼交換 if
宣告中判斷的內容,要麼確保使用 >=
。
打賞支援我翻譯更多好文章,謝謝!
打賞譯者
打賞支援我翻譯更多好文章,謝謝!