目標Python2+3
很多時候你可能希望你開發的程式能夠同時相容Python2+和Python3+。
試想你有一個非常出名的Python模組被很多開發者使用著,但並不是所有人都只使用Python2或者Python3。這時候你有兩個辦法。第一個辦法是開發兩個模組,針對Python2一個,針對Python3一個。還有一個辦法就是調整你現在的程式碼使其同時相容Python2和Python3。
我將介紹一些技巧,讓你的指令碼同時相容Python2和Python3。
Future模組匯入
第一種也是最重要的方法,就是匯入__future__
模組。它可以幫你在Python2中匯入Python3的功能。這有一組例子:
上下文管理器是Python2.6+引入的新特性,如果你想在Python2.5中使用它可以這樣做:
from __future__ import with_statement
在Python3中print
已經變為一個函式。如果你想在Python2中使用它可以通過__future__
匯入:
print
# Output:
from __future__ import print_function
print(print) # Output: <built-in function print>
模組重新命名
首先,告訴我你是如何在你的指令碼中匯入模組的。大多時候我們會這樣做:
import foo
# or
from foo import bar
你知道麼,其實你也可以這樣做:
import foo as foo
這樣做可以起到和上面程式碼同樣的功能,但最重要的是它能讓你的指令碼同時相容Python2和Python3。現在我們來看下面的程式碼:
try:
import urllib.request as urllib_request # for Python 3
except ImportError: import urllib2 as urllib_request # for Python 2
讓我來稍微解釋一下上面的程式碼。
我們將模組匯入程式碼包裝在try/except
語句中。我們是這樣做是因為在Python 2中並沒有urllib.request
ImportError
異常。而在Python2中urllib.request
的功能則是由urllib2
提供的。所以,當我們試圖在Python2中匯入urllib.request
模組的時候,一旦我們捕獲到ImportError
我們將通過匯入urllib2
模組來代替它。
最後,你要了解as
關鍵字的作用。它將匯入的模組對映到urllib.request
,所以我們通過urllib_request
這個別名就可以使用urllib2
中的所有類和方法了。
過期的Python2內建功能
另一個需要了解的事情就是Python2中有12個內建功能在Python3中已經被移除了。要確保在Python2程式碼中不要出現這些功能來保證對Python3的相容。這有一個強制讓你放棄12內建功能的方法:
from future.builtins.disabled import *
現在,只要你嘗試在Python3中使用這些被遺棄的模組時,就會丟擲一個NameError
異常如下:
from future.builtins.disabled import *
apply()
# Output: NameError: obsolete Python 2 builtin apply is disabled
標準庫向下相容的外部支援
有一些包在非官方的支援下為Python2提供了Python3的功能。例如,我們有:
- enum
pip install enum34
- singledispatch
pip install singledispatch
- pathlib
pip install pathlib