[譯文]python2還是python3

原文: https://wiki.python.org/moin/Python2orPython3

在項(xiàng)目開發(fā)中馆纳,我應(yīng)該用python2還是python3?

它們之間有什么區(qū)別逮京?

簡而言之,python2.x是過去;python3.x是現(xiàn)在峡继、是將來岸梨。

在2008年的時候,python3.0發(fā)布篷扩。python2.x的最后版--v2.7也于2010年年中發(fā)布兄猩,并且聲明了對最后一版的延長支持。在這之后鉴未,python2.x分支就沒有任何主要的新屬性發(fā)布枢冤。3.x版本一直持續(xù)開發(fā),并且已經(jīng)發(fā)布了5年的穩(wěn)定版本铜秆。2012年發(fā)布3.3淹真,2014年發(fā)布3.4,2015年發(fā)布3.5连茧,2016年發(fā)布3.6趟咆。這意味著新開發(fā)的標(biāo)準(zhǔn)庫只在python3.x中展現(xiàn)。

在最新的2.x發(fā)布版本中梅屉,Guido van Rossum(python的創(chuàng)造者)決定適當(dāng)?shù)那謇韕ython2.x值纱,以減少向后兼容性。最大的改變是更好的unicode編碼支持(默認(rèn)情況下所有文字都轉(zhuǎn)換成unicode)與更加健全的bytes/unicode編碼分離坯汤。

此外虐唠,在幾個核心語言層面,做了一些調(diào)整(如惰聂,print與exec是聲明疆偿,整數(shù)使用向下取整)。這些改變對初學(xué)者來說搓幌,更加容易學(xué)習(xí)杆故。對Python其他部分也更加易用。一些老舊的丑陋的代碼被移除溉愁,舉個例子处铛,所有的類都是new-style,"range"函數(shù)不再像python2.x一樣返回list, 而是返回一個內(nèi)存利用率高的迭代器。

《python3.0中的新特性》對于主要的語言層改變以及與python2.x源碼可能存在的兼用性做了一個很好的概述拐揭。Nick Coghlan(CPython開發(fā)者之一)也創(chuàng)建了一個relatively extensive FAQ來處理python版本過渡問題撤蟆。

然而,在過去的時間里堂污,龐大的python生態(tài)系統(tǒng)已經(jīng)累積了大量的重要的高質(zhì)量的軟件家肯。對python3.x的兼容的最大問題就是,某些軟件(尤其是一些公司內(nèi)部軟件)任然不能再python3.x下正常運(yùn)行盟猖。

該如何選擇我要使用的版本讨衣?

如何選擇版本换棚,主要依賴于你想要做什么。

如果你明確的知道用python3想要做什么。很好,這里有少許次要的缺陷或不足链方,如不是太嚴(yán)重的軟件庫支持問題福荸,還有一個客觀事實(shí)是,現(xiàn)在的很多l(xiāng)inux發(fā)行版和mac都是將python2作為默認(rèn)python版本(雖然在很多系統(tǒng)中,python3也被安裝了),python3有著一個語言應(yīng)該有的所有特性。如果你能控制你所安裝的環(huán)境并且你明確知道你不需要python2的模塊风秤,使用python3是一個很好的選擇。現(xiàn)在扮叨,很多的linux發(fā)行版已經(jīng)內(nèi)置了python3缤弦。并且所有這些都適用于終端用戶。一些linux已經(jīng)開始淘汰python2作為內(nèi)置python版本彻磁。

特別指出的是碍沐,很多教師或書籍在介紹python的時候都會首先考慮python3,而后衷蜓,如果有必要累提,再介紹python3與python2的不同之處。因?yàn)閜ython3移除了一些磁浇,初學(xué)者學(xué)習(xí)python2而踩的一些不必要的坑斋陪。

然而,任然有一些問題需要你必須用python2而不是用python3置吓。

  • 你的應(yīng)用所部署的環(huán)境是一個你不能控制的无虚。這個環(huán)境中使用了特殊版本的python,而不是讓你自由選擇python版本衍锚。
  • 你依賴的三方庫沒有兼容python3友题。并且這個庫是一個不可或缺或及其重要的庫。

python3在使用創(chuàng)建GUI應(yīng)用已經(jīng)得到了廣泛的支持戴质。包Tkinter作為標(biāo)準(zhǔn)庫度宦。從python3發(fā)布開始,PyQt也被支持置森。 在2011年斗埂,PySide被支持符糊。PyGObject作為PyGtk的替代品也被支持凫海。

這里列舉了一些主要的支持python3的包:

如果你想使用python3,但是你又害怕依賴兼容性問題。使用之前建瘫,做一些調(diào)研是值得的崭捍。這是一個持續(xù)跟進(jìn)的過程,這篇wiki也可能過時啰脚。此外殷蛇,有著對于python2.6+與python3.3+的大量支持,現(xiàn)在很多的python代碼都不需要做較大的修改就可以運(yùn)行在python3上橄浓。尤其是用于web與GUI框架的代碼粒梦,這些框架強(qiáng)制應(yīng)用區(qū)別二進(jìn)制數(shù)據(jù)與文本(six compatiblility module可以用來修補(bǔ)這些問題)。

雖然官方文檔tutorial對python3鏡像完整的更新荸实。但是在網(wǎng)上與一些相關(guān)的書籍中的大量的文檔是使用python2匀们。這些文檔雖然也在不斷的更新。當(dāng)用python3來運(yùn)行的時候需要做一些調(diào)整准给。

有些人不想用python3泄朴。這是他們的權(quán)利。畢竟是少數(shù)人露氮。

如果你想用其他一些python執(zhí)行環(huán)境祖灰,如IronPython,Jython 或Pyston等等,使用python3是不值得的畔规。在這些平臺中python3的支持還是不太理想夫植。當(dāng)你應(yīng)為系統(tǒng)的完整性或性能等等原因而選擇前面所說的執(zhí)行環(huán)境的時候,這個因素(在這些平臺上油讯,python3支持有限)將會影響你详民。

難道我不想避免使用python2? python2是一門有許多錯誤的老語言了,python已經(jīng)開了一個主版本來移除這些錯誤陌兑。

good, 也不完全是沈跨,一些python3.0,python3.1的斷層式的修改已經(jīng)各自被移植到python2.6, 2.7。更多的移植相關(guān)兔综,參見What's New in Python2.6What's New in Python2.7

對于哪些屬性只能用在python3與哪些屬性不能移植到python2沒有一個詳盡的列表列出饿凛。

  • 字符串默認(rèn)編碼為Unicode
  • 清除unicode與bytes分離
  • 異常鏈
  • 函數(shù)注解
  • 關(guān)鍵詞參數(shù)語法
  • 擴(kuò)展的tuple解包
  • 沒有局部變量定義

語言版本的更迭,并沒有限制核心代碼的改變软驰。在標(biāo)準(zhǔn)庫中涧窒,一些在python3中的改善并沒有直接移植到python2。參見What's New in Python3锭亏。一些標(biāo)準(zhǔn)庫的提升可以通過PyPI找到纠吴。

也就是說,用python2寫的代碼更加像python3的代碼慧瘤。這可以代表很多事情戴已。包括使用新類型的classe固该,不使用古老的棄用的print用法,使用懶加載的迭代器糖儡。舉個例子伐坏,好的python2代碼會用xrange來代替range。xrange最開始在python3上的range實(shí)現(xiàn)(當(dāng)然握联,range在python3中表現(xiàn)更好一些桦沉,因?yàn)樗梢詇andle住超過sys.maxint的值)。有點(diǎn)值得注意的是xrange()在python3中沒有被定義金闽。

最終要的是永部,python2或python3只是些小問題,你真正應(yīng)該做的是寫好好代碼呐矾。這些代碼包含完整的單元測試苔埋,正確的使用unicode。(在unicode與bytes問題上蜒犯,python3相對于python2更少的操心组橄。這是一件好事情,雖然這讓一些軟件包的移植變得相對來說比較惡心)

我想用Python3,但是想用的一些庫只有python2罚随。難道我只能不得不重新回去使用python2或者放棄使用這個庫玉工?

假設(shè)你找不到在python3中支持替代包,你可以看看下面的幾種建議:

  • 移植這個庫到python3 ("porting"意味著你需要讓這個庫能正常的在python3上運(yùn)行)
  • 如果實(shí)在是實(shí)現(xiàn)比較困難淘菩,并且你的其他依賴也是用python2,你可以開始的時候用python2遵班。隨著庫在其他地方被移植的,一旦每一個依賴庫度偶做好了移植潮改,好的python2代碼可以進(jìn)行輕松的切換狭郑。
  • 好好想想這個庫是否真的很重要?或許你可以不使用它汇在。

最理想的狀態(tài)是你試著移植到python3,你經(jīng)常發(fā)現(xiàn)有人使用它翰萨,即使不是當(dāng)前庫,其他成員通常會感激你的糕殉。尤其是移植中發(fā)現(xiàn)原始的bug亩鬼。這樣做可以提高原始版本與python3移植版本的質(zhì)量。移植不是一帆風(fēng)順的,但總是比你自己從頭開始寫容易阿蝶。

Python2 porting guide中雳锋,你可以知道如何移植庫。最基本的思想是使用python2庫羡洁,在python2中使用-3 命令切換玷过,檢查所有的單元測試通過,而沒有警告。如果測試失敗冶匹,或者發(fā)出了警告信息习劫。修改源碼咆瘟,再一次做單元測試(這可能需要在老的版本中降低兼容性)嚼隘。當(dāng)沒有警告信息的時候,可以試著用python3運(yùn)行這個庫了袒餐。最好的可能的狀態(tài)是運(yùn)行的代碼是python2,python3兼容的飞蛹,這時候,移植完成灸眼。

如果在python3中卧檐,單元測試任然失敗。那么標(biāo)準(zhǔn)庫中的2to3組件能夠自動生成運(yùn)行在python3下的版本焰宣∶骨簦或者Armin Ronacher的python-modernize組件可以用于python2.6+和3.2+或者3.3+(這依賴于命令行輸出參數(shù))。如果你使用python-modernize匕积,同樣需要在Python2下做單元測試盈罐。

任一種方法都可以從單個python2代碼庫并行支持python2和python3。將python2與python3分開維護(hù)更加容易一些闪唆。(可以問問核心代碼開發(fā)者盅粪,他們這么做已經(jīng)很多年了)

如果自動轉(zhuǎn)換后,測試失敗悄蕾,有可能是因?yàn)閜ython3與python2的語義變化票顾。這些變化有可能導(dǎo)致轉(zhuǎn)換器自動轉(zhuǎn)換失敗,-3 switch也沒有檢測出來帆调。這些問題不多奠骄,但是也是存在的。當(dāng)你遇到的時候番刊,提交一個bug給CPython,請求一個新的 -3 警告戚揭,是非常值得的。

如果包含c擴(kuò)展或者工程沒有使用想CPython,cffi,SWIG這些能夠值得處理python2與python3之間的差異的包裹生成器撵枢,移植過程可能更加復(fù)雜民晒。但是還是會比你自己開發(fā)相同功能的包更容易一些。extension porting guide介紹了一些它們之間的主要的不同之處锄禽。

這里是一些比較深入的guide:PortingPythonToPy3k,PortingExtensionModulesToPy3k

我想用python3寫一些東西潜必,但是有些人只用python2,我該怎么辦?

除了有能夠從python2代碼生成python3代碼的2to3工具沃但,還有轉(zhuǎn)換python3代碼到python2代碼的3to2工具磁滚。理論上,可以3to2可能比2to3工作得更好,因?yàn)閜ython3對轉(zhuǎn)換器轉(zhuǎn)換來數(shù)垂攘,清理掉了許多惡心的死角問題(畢竟维雇,盡可能擺脫更多的這種問題是打破向后兼容性的主要原因之一)。然而晒他,那些嚴(yán)重依賴python3特有屬性的代碼(例如函數(shù)注解吱型,擴(kuò)展版tuple unpacking)是不可能轉(zhuǎn)換成功的。

可以舉個恰當(dāng)?shù)谋确剑?to2相對于2to3來說是一條更少旅人的路你可能遇到一些邊邊角角陨仅。如果你想用python3, 這些是值得探索的津滞。

在一些通用模塊代碼中支持python2與python3

python2.6+與python3.3+有大量的相同之處。例如,在python3中對unicode字符串前面加'u'字符的恢復(fù)意味著語義上正確的python2.6+代碼可以與python3.3+兼容灼伤,同時保留著大量的慣用的python触徐。主要的不同是來自不同地方的代碼需要被修改,這樣才可以處理python2與python3之間的命名問題狐赡。

因此撞鹉,six compatibility package是在單一庫中支持python2與python3最主要的實(shí)用程序。

future compatibility package任然在測試中颖侄,并且不像six包一樣支持如此多的python版本(future只支持到python2.6, six可以支持到python2.4)鸟雏。但是future運(yùn)行python2兼容代碼可以寫得跟python3通用代碼一樣的風(fēng)格(例如,它包含了python2兼容python3中bytes類型實(shí)現(xiàn)代碼发皿,而不是依賴于python2中的字節(jié)字符串類型崔慧,他們兩個是不同的API)。

其他一些確定標(biāo)準(zhǔn)庫的主要的因素是是否存在一個更新的對PyPi的移植穴墅,這些移植優(yōu)先用于python2標(biāo)準(zhǔn)庫惶室。下面所列的這些模塊要么是對PyPI的移植,要么是原生支持python2.7與python3標(biāo)準(zhǔn)庫:

  • unittest2(Michael Foord, 標(biāo)準(zhǔn)庫unittest維護(hù)者, 需要2.6支持)
  • mock(Michael Foord, 標(biāo)準(zhǔn)庫unittest.mock維護(hù)者)
  • contextlib2(Nick Coghlan, 標(biāo)準(zhǔn)庫contextlib維護(hù)者)
  • configparser(?ukasz Langa, 標(biāo)準(zhǔn)庫configparser維護(hù)者)
  • futures(Alex Gr?nholm and Brian Quinlan, 標(biāo)準(zhǔn)庫concurrent.futures維護(hù)者)
  • argparse(Steven Bethard, 標(biāo)準(zhǔn)庫argparse維護(hù)者, 需要2.6支持)
  • faulthandler(Victor Stinner,標(biāo)準(zhǔn)庫faulthandler維護(hù)者)
  • cdecimal(Stefan Krah, 標(biāo)準(zhǔn)庫decimal維護(hù)者)
  • ipaddr((Peter Moody, 標(biāo)準(zhǔn)庫ipaddress維護(hù)者)
  • stats(Steven D'Aprano, 標(biāo)準(zhǔn)庫statistics維護(hù)者)
  • enum34(Ethan Furman,標(biāo)準(zhǔn)庫enum維護(hù)者)
  • funcsigs(Aaron Iles,移植于函數(shù)signature objects)
  • shared namespace module for backports(Brandon Craig Rhodes)
  • backports.inspect(Tripp Lilley, 額外的inspect移植,基于funcsigs)
  • backports.datetime_timestamp(Jason R. Coombs, datetime.timestamp的移植)
  • backports.pbkdf2(Christian Heimes, 標(biāo)準(zhǔn)庫hashlib維護(hù)者, 對hashlib.pbkdf2_hmac的移植)
  • backports.ssl_match_hostname(Brandom Craig Rhodes 與 Toshio Kuratomi, ssl.match_hostname的移植)
  • backports.lzma(Peter Cock, lzma wrapper模塊的移植)
  • lzmaffi(Tomer Chachamu, lzma的移植)
  • tracemalloc(Victor Stinner, 標(biāo)準(zhǔn)庫tracemalloc的維護(hù)者)
  • pathlib(Antoine Pitrou, 標(biāo)準(zhǔn)庫pathlib的維護(hù)者)
  • selectors34(Berker Peksag,標(biāo)準(zhǔn)庫selectors的移植)

當(dāng)在交叉版本的標(biāo)準(zhǔn)庫之間使用玄货,使用移植版本的命名空間模塊可以清楚的指明皇钞。原始版本的屬性可以使用而不會產(chǎn)生沖突。

下面的模塊不是移植版本松捉。但是可以替換標(biāo)準(zhǔn)版本的各個版本兼容的庫夹界。

  • requests(對http/https更高級封裝的api)
  • regex(一個替代的正則表達(dá)式引擎)
  • lxml.etree(ElementTree XML API的替代實(shí)現(xiàn))

上面的這些模塊也支持python2。在python3.4中隘世,asyncio模塊被添加到標(biāo)準(zhǔn)庫中可柿。

  • asyncio(Guido van Rossum, BDFL and標(biāo)準(zhǔn)庫 asyncio維護(hù)者)

其他一些有助于在python2,python3做選擇的資源

補(bǔ)充說明

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末复斥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子械媒,更是在濱河造成了極大的恐慌目锭,老刑警劉巖评汰,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異痢虹,居然都是意外死亡被去,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門奖唯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惨缆,“玉大人,你說我怎么就攤上這事臭埋∽傺耄” “怎么了臀玄?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵瓢阴,是天一觀的道長。 經(jīng)常有香客問我健无,道長荣恐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任累贤,我火速辦了婚禮叠穆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘臼膏。我一直安慰自己硼被,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布渗磅。 她就那樣靜靜地躺著嚷硫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪始鱼。 梳的紋絲不亂的頭發(fā)上仔掸,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音医清,去河邊找鬼起暮。 笑死,一個胖子當(dāng)著我的面吹牛会烙,可吹牛的內(nèi)容都是我干的负懦。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼柏腻,長吁一口氣:“原來是場噩夢啊……” “哼纸厉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起葫盼,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤残腌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抛猫,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蟆盹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了闺金。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逾滥。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖败匹,靈堂內(nèi)的尸體忽然破棺而出寨昙,到底是詐尸還是另有隱情,我是刑警寧澤掀亩,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布舔哪,位于F島的核電站,受9級特大地震影響槽棍,放射性物質(zhì)發(fā)生泄漏捉蚤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一炼七、第九天 我趴在偏房一處隱蔽的房頂上張望缆巧。 院中可真熱鬧,春花似錦豌拙、人聲如沸陕悬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捉超。三九已至,卻和暖如春逞敷,著一層夾襖步出監(jiān)牢的瞬間狂秦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工推捐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裂问,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓牛柒,卻偏偏與公主長得像堪簿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子皮壁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容