Python 如何移除舊的版本特性,如何迎接新的特性?

2020 年 4 月 20 日,Python 2 的最後一個版本 2.7.18 發佈了,這意味着 Python 2 是真正的 EOL(end of life)了,一個時代終於落幕了。python

Python 2.0 版本是在 2000 年發佈的,至今正好到 20 週年(差半年),一代版本居然持續了這麼長時間。其中,2.7 版本是在 Python 3 推出後才發佈的,它在 2010 年發佈,至今已經是 10 年之久。程序員

事實上,Python 誕生了 30 年,但版本演進過程一直很慢,目前最新發布的版本只到 3.8.2。編程

對比一下相差幾歲的隔壁家選手,C++ 已經發展到了 20,JAVA 發展到了 14 ,PHP 到了 7.4,差距懸殊。性能優化

可是,版本發佈太頻繁,也不老是一件好事。就在 Python 程序員抱怨本身的 Python 2 項目還沒升 3 版本時,有些 JAVA 程序員還在維護 六、7 版本的項目呢。版本遷移之苦,你們彼此彼此,五十步笑百步。多線程

編程語言跨版本間出現不兼容的特性,幾乎是常態。不少時候,並非說過去的設計是 bug,只是由於編程語言也是某種「生命體」,它會學習其它語言,也會自我進化,因此就有新陳代謝。併發

擺脫舊的不兼容性版本或者某些落後的設計,有時候須要挺漫長的過渡期。爲了方便程序員遷移,核心開發者們造成了一些有效的慣例。異步

以 Python 爲例,我知道有如下的幾種策略:async

一、DeprecationWarning 提示

當使用過時的類或方法時,會出現 DeprecationWarning 告警。編程語言

例如,從 collections 模塊導入 ABC(Abstract Base Classes,即抽象基類)就是過時用法,會出現如下提示:性能

> DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.9 it will stop working

從 3.3 版本起,正確的用法是from collections.abc import Iterable ,直到 3.9 版本時,會取消過時提示,出現報錯。

二、將模塊更名,約定爲私有

在 Python 中,以單下劃線「_」開頭命名的變量,會被約定爲私有的。若是在一個模塊中定義了私有變量,理論上它就不應被導出到其它模塊使用。

這種命名方式也被推廣到了標準模塊上。例如,在 Python 的極早期版本中有一個thread 模塊,後來到 1.5.1 版本,以 thread 爲基礎又推出一個更方便好用的threading 模塊,也就是咱們熟知的實現多線程的模塊。

爲了擺脫/屏蔽舊的實現,Python 把 thread 模塊重命名爲_thread ,約定爲私有的,這種方式很靈活,普通程序員不會感知它的存在,骨灰級程序員卻能夠用它實現更加低層的開發。

三、文檔中做 deprecated 提示

它跟 DeprecationWarning 是一樣的意思。之因此要單獨列出來,是由於在構思本文時,我正巧在 Python 3.8 文檔中發現了一則提示,忍不住分享一下。

文檔中說: @asyncio.coroutine 裝飾器再也不支持基於yield from 生成器實現的協程,須要顯式地寫成「asyc def」這種定義方式。

這意味着,3.8 版本對該特性來講就是個分界線,它將進入一個平穩的淘汰週期。

以上三種方式可謂是「除舊」,是面向過去的版本所作的。與它們相對應,就少不了「迎新」的過程,要面向將來的版本。

Python 中有時候會在當前版本中加入一些實驗性的特性,期待在將來版本中再徹底地實現。而這,就須要給程序員們指出一些過渡性的提示。

例如,在《Python 3.9 性能優化:更快的 list()、dict() 和 range() 等內置類型》一文中,我就介紹了隱藏在 3.8 版本中的「vectorcall」協議,它要在 3.9 版本中才會真正地實現(並且不排除在將來還會繼續擴展)。

此外,還有一個很著名的例子:3.2 版本中推出的 concurrent.futures 標準庫(依據 PEP-3148)。

這是一個統合了多線程與多進程的異步開發庫,「concurrent」指的是併發,而「併發」概念能夠囊括多線程與多進程的實現方式。

爲何在「concurrent」下面要加一個「futures」呢?PEP-3148 中指出了這樣命名的三點緣由,其中最後一點是:但願在未來(in the future)可以添加和移動現有的跟併發相關的庫到concurrent 庫下面。

也就是說,3.2 版本的concurrent.futures 就是一種實驗性的設計,它是爲未來更好的concurrent 庫而做的準備。雖說未來的最終實現,可能跟 PEP 中設想的不一樣,可是,這種面向未來的長遠考慮的設計思路,會給整個社區帶來某種預期和共同的信念。

好了,聊了這麼多,是時候收個尾了。

我從未真正開發或維護過 Python 2 的項目,因此在這個本應記念它 EOL 的日子,所能想到的就是一個更具廣泛性的「除舊迎新」的話題:舊的版本特性是如何逐步退出的,新的版本特性又是如何逐步加入的?

若是你喜歡這種風格的文章,歡迎搜索關注公衆號「Python貓」。人生苦短,讓咱們一塊兒用 Python!

推薦閱讀:

本文首發地址:https://mp.weixin.qq.com/s/PIhtEIzBgy_ujcTeAQ2dxg

一、Python 3.9 性能優化,更快的 list()、dict() 和 range() 等內置類型:https://mp.weixin.qq.com/s/bjQjVmf7dP5fOqCS1cObqQ

二、PEP-3148:https://www.python.org/dev/peps/pep-3148

三、聊聊 Python 的內置電池:https://mp.weixin.qq.com/s/XzCqoCvcpFJt4A-E4WMqaA

四、聊聊 print 的前世此生:https://mp.weixin.qq.com/s/NuzfuH_zCZzcrmSFR04NHw

相關文章
相關標籤/搜索