鍍金池/ 教程/ Python/ 22. 目標Python2+3
<code>open</code>函數(shù)
Python 2系列版本
可迭代對象(Iterable)
異常
在函數(shù)中嵌入裝飾器
你的第一個裝飾器
上下文管理器(Context managers)
<code>set</code>(集合)數(shù)據(jù)結構
裝飾器類
字典推導式(<code>dict</code> comprehensions)
<code>Reduce</code>
捐贈名單
<code>Filter</code>
<code>try/else</code>從句
*args 的用法
<code>dir</code>
處理異常
<code>else</code>從句
對象自省
For - Else
18. 一行式
Python 3.2及以后版本
Global和Return
基于類的實現(xiàn)
容器(<code>Collections</code>)
23. 協(xié)程
推薦閱讀
譯者后記
<code>*args</code> 和 <code>**kwargs</code>
**kwargs 的用法
生成器(Generators)
迭代(Iteration)
基于生成器的實現(xiàn)
將函數(shù)作為參數(shù)傳給另一個函數(shù)
日志(Logging)
三元運算符
<code>inspect</code>模塊
枚舉
Map,F(xiàn)ilter 和 Reduce
各種推導式(comprehensions)
從函數(shù)中返回函數(shù)
列表推導式(<code>list</code> comprehensions)
處理多個異常
帶參數(shù)的裝飾器
對象變動(Mutation)
22. 目標Python2+3
迭代器(Iterator)
虛擬環(huán)境(virtualenv)
<code>__slots__</code>魔法
什么時候使用它們?
Python/C API
<code>Map</code>
SWIG
授權(Authorization)
裝飾器
一切皆對象
使用C擴展
使用 <code>*args</code> 和 <code>**kwargs</code> 來調用函數(shù)
17. <code>lambda</code>表達式
集合推導式(<code>set</code> comprehensions)
<code>type</code>和<code>id</code>
在函數(shù)中定義函數(shù)
<code>finally</code>從句
CTypes
調試(Debugging)
使用場景
生成器(Generators)
多個return值
關于原作者
函數(shù)緩存 (Function caching)
Python進階

22. 目標Python2+3

很多時候你可能希望你開發(fā)的程序能夠同時兼容Python2+和Python3+。

試想你有一個非常出名的Python模塊被很多開發(fā)者使用著,但并不是所有人都只使用Python2或者Python3。這時候你有兩個辦法。第一個辦法是開發(fā)兩個模塊,針對Python2一個,針對Python3一個。還有一個辦法就是調整你現(xiàn)在的代碼使其同時兼容Python2和Python3。

本節(jié)中,我將介紹一些技巧,讓你的腳本同時兼容Python2和Python3。

Future模塊導入

第一種也是最重要的方法,就是導入__future__模塊。它可以幫你在Python2中導入Python3的功能。這有一組例子:

上下文管理器是Python2.6+引入的新特性,如果你想在Python2.5中使用它可以這樣做:

from __future__ import with_statement

在Python3中print已經變?yōu)橐粋€函數(shù)。如果你想在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?,F(xiàn)在我們來看下面的代碼:

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代碼中不要出現(xiàn)這些功能來保證對Python3的兼容。這有一個強制讓你放棄12內置功能的方法:

from future.builtins.disabled import *

現(xiàn)在,只要你嘗試在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

想更多了解,在Python文檔中有一個全面的指南可以幫助你讓你的代碼同時兼容Python2和Python3。