為什么向 Python 3遷移需要這么長時(shí)間?
在 2014 年的 Pycon 中,Python 的發(fā)明人 Guido van Rossum 說:“現(xiàn)在是進(jìn)入 Python 3 的時(shí)候了!”-- 他告訴現(xiàn)場(chǎng)聽眾應(yīng)該開始在工作中采用 Python3。
經(jīng)過核心代碼貢獻(xiàn)者和開源社區(qū)的多年努力,Python 2 終于壽終正寢了。根據(jù) pythonclock.org 的說法,2020 年 1 月 1 日是支持 Python 2 的截止日期。對(duì)于幾年前已經(jīng)做出 Python3 遷移的一些公司來說,這將不是問題。但是,出于多種原因,很多公司都不會(huì)在短期內(nèi)進(jìn)行 Python2 遷移。
對(duì)于大量使用 Python 的公司,特別是那些近期可能不準(zhǔn)備遷移 Python2 的公司,此更改意味著什么?要了解正在發(fā)生的事情的整個(gè)上下文,讓我們回顧一下 Python 的歷史。
1. Python 簡史
開發(fā) Python 3 的想法是實(shí)現(xiàn)一些重大的改變,如擺脫了 Python 的遺留問題:將所有字符串都呈現(xiàn)為 Unicode。正如 Python 的核心開發(fā)人員之一布雷特·坎農(nóng)(Brett Cannon)寫道:
人們有時(shí)會(huì)忘記 Python 誕生的年代。
Guido 于 1989 年 12 月開始對(duì) Python 進(jìn)行編碼,并于 1991 年 2 月首次以開源形式發(fā)布。這意味著 Python 本身早于 1991 年 10 月發(fā)布的 Unicode 標(biāo)準(zhǔn)的第一版。在隨后的幾年中,Unicode 標(biāo)準(zhǔn)化后創(chuàng)建的語言選擇使用基于 Unicode 編碼字符串的實(shí)現(xiàn)。
支持任何語言的 Unicode 和文本非常重要。
Python 是一種世界語言,不僅是支持 ASCII 覆蓋的羅馬字母的語言,這就是為什么 Python 3 在處理文本時(shí)將其默認(rèn)設(shè)為“ Unicode”的原因。它保證了所有 Python 3 代碼都將支持世界上的每個(gè)人,無論編寫該代碼的開發(fā)人員是否明確為其指定 Unicode 編碼。
不幸的是,該團(tuán)隊(duì)假設(shè)每個(gè)人都將立即進(jìn)行大的切換,并使 Python 3 向后不兼容,并將 Python 2 設(shè)置為維護(hù)分支。但是,許多人不想切換,因?yàn)檎绺倪M(jìn)的 PEP 所說,Python 3 是“相對(duì)于 Python 2 的溫和的改進(jìn)。”許多人并沒有因?yàn)檫@些帶來的不便而切換。當(dāng)時(shí),Python2、3 最大的區(qū)別是將 print 語句更改為 print() 函數(shù)語法,這破壞了很多 Python 2 代碼。
結(jié)果,此后很多年 Python 2 還繼續(xù)處于積極的開發(fā)中。
不過,在 2019 年,Python 3 終于成為了新 Python 軟件工程師(大部分)開發(fā)的默認(rèn)語言版本,現(xiàn)在許多公司和項(xiàng)目都在使用 Python 3 的主要功能:f- 字符串、Path、類型提示、異步,當(dāng)然還包括 Unicode 編碼。
2. 緩慢的迭代過程
自從新的版本于 2008 年宣布以來,Python 3 市場(chǎng)份額增長一直很漫長:
最初,有很多理由不采用 Python 3:最重要的是,它與 Python 2 并沒有向后兼容。結(jié)果導(dǎo)致一些 Python2 的主要庫往 Python3 遷移都猶豫不決。2 向 3 轉(zhuǎn)換的轉(zhuǎn)折點(diǎn)發(fā)生在大約 2016 年左右的 Python 3.5 發(fā)行版中,該版本具有矩陣乘法、asyncio 的引入、OrderedDict 的速度改進(jìn)以及類型提示的實(shí)現(xiàn),這些提示為 Python3 帶來了一些類似于靜態(tài)語言的實(shí)用功能。
Python3 更高版本包含更多功能,例如 Pathlib 庫和 f- 字符串操作。通過這些更改,人們使用了許多庫(例如用于機(jī)器學(xué)習(xí)的 scikit-learn)開始了向 Python 3 的遷移。
隨著越來越多的依賴關(guān)系開始升級(jí),一些公司也開始遷移 Python3。
從互聯(lián)網(wǎng)上的狀況來看,您可能以為每個(gè)人都完成了 Python3 遷移。
在 Jetbrains 進(jìn)行的一項(xiàng)調(diào)查中,他們制作了 IntelliJ 和 PyCharm 之類的 IDE,有 75%的個(gè)人受訪者表示他們已經(jīng)遷移到 Python3。一連串的博客文章都顯示了相同的內(nèi)容,例如,Dropbox 于 2018 年秋季詳細(xì)說明了他們的遷移 Python3、Instagram 于 2017 年遷移 Python3、Facebook 于 2014 年開始遷移 Python3。在客戶的敦促下,Splunk 最近也這樣做了 -- 往 Python3 遷移。
但是,僅僅因?yàn)?Python 2 即將到期,并不意味著公司會(huì)在一夜之間停止使用它。我們?cè)趺粗?Python 2 仍在大量的使用?我們可以直接檢查 Python 包庫 PyPI 的運(yùn)行情況。2016 年,PyPI 核心開發(fā)人員開始將日志發(fā)送到 Google 的 BigQuery,以便能夠針對(duì)它們運(yùn)行 SQL,這使得根據(jù)使用情況做出體系結(jié)構(gòu)決策變得更加容易。
例如,如果要查看過去 30 天內(nèi)通過 Python 版本下載了哪些庫,則可以在 BigQuery 中創(chuàng)建一個(gè)新項(xiàng)目(每月查詢的前 1TB 是免費(fèi)的),然后運(yùn)行:
- SELECT
- REGEXP_EXTRACT(details.python, r"^([^\.]+\.[^\.]+)") as python_version,
- COUNT(*) as download_count,
- FROM
- TABLE_DATE_RANGE(
- [the-psf:pypi.downloads],
- DATE_ADD(CURRENT_TIMESTAMP(), -31, "day"),
- DATE_ADD(CURRENT_TIMESTAMP(), -1, "day")
- )
- GROUP BY
- python_version,
- ORDER BY
- download_count DESC
- LIMIT 100
盡管 Python 3 一直是社區(qū)中的主導(dǎo)版本至少一年,但從 PyPI 下載的單個(gè)軟件包的最新數(shù)量顯示,2019 年 9 月所有軟件包下載中至少有 40%為 2.7 版本。誠然,這比年初的 60%有所下降,但是鑒于 EOL 距離只有數(shù)月之遙,所以這個(gè)數(shù)據(jù)仍然很重要。
在每個(gè)庫的基礎(chǔ)上,它變得有些棘手:大多數(shù) Flask 下載都是使用 Python 3 版本完成的,但是只有 26%的 botocore 下載(適用于 Python 的 AWS 開發(fā)工具包)正在使用 Python 3。
而且,有幾個(gè)庫需要進(jìn)行遷移:Twisted 和 PyPy(常用的 JIT 編譯器)將無限期保留版本 2。
任何給定軟件的壽命終止通常并不意味著該軟件不再可用。這確實(shí)意味著它不再針對(duì)任何安全漏洞或添加任何其他錯(cuò)誤修復(fù)程序進(jìn)行更新。但是,不更新到 Python 3 會(huì)帶來很多風(fēng)險(xiǎn) - 最重要的是,可能會(huì)丟失安全更新,無法利用類型提示和速度提升等新功能。
3. 為什么 Python3 遷移速度這么慢?
開個(gè)玩笑,在我寫本文的時(shí)候,我的 IT 系統(tǒng)還在 Java 8 上運(yùn)行(按今天的標(biāo)準(zhǔn),這已經(jīng)很古老了。但是根據(jù) 2018 年的 JVM 生態(tài)系統(tǒng)報(bào)告,Java 8 仍然是主要的開發(fā)環(huán)境。)
這就是答案:大多數(shù)大型組織,在技術(shù)新聞發(fā)布的炒作周期之外,其行動(dòng)要比新聞媒體或博客想像的要慢得多。例如,大多數(shù)主要銀行仍在運(yùn)行 FORTRAN 和 COBOL 的編程語言系統(tǒng)。
因此,盡管許多公司描述了他們的遷移策略,但更多的應(yīng)用軟件將長期保留在 Python 2 上。
為什么會(huì)這樣呢?
在所有決策中,政治發(fā)揮的作用和技術(shù)指導(dǎo)一樣重要
例如,為了在 Facebook 上使用 Python 3,Jason Fried 從 2014 年開始重寫 Python3 服務(wù)。一路走來,他犯了很多錯(cuò)誤,更改了很多代碼,并做了很多修改以使其廣為人知人們正在做 Facebook 之類的事情,例如參加新的開發(fā)人員培訓(xùn),從而開始使用 Python 3。然后,他與ŁukaszLanga 合作,后者將 Instagram 轉(zhuǎn)換為 Python 3: 2016 年,他和 Langa 在 Facebook 上組建了一個(gè)全新的團(tuán)隊(duì),以在公司內(nèi)部管理 Python3。由于他們是“ Python 團(tuán)隊(duì)”,因此他先前提到的“公認(rèn)權(quán)威”起作用。人們認(rèn)為他們可以在 Facebook 上做出有關(guān) Python 的決定。
實(shí)際上,Instagram 的遷移項(xiàng)目本身耗時(shí) 10 個(gè)月。
Guido 和 Langa 現(xiàn)在工作的 Dropbox 花費(fèi)了三年時(shí)間,而直到 Guido 幾周前退休為止,它仍在進(jìn)行中。
誠然,上面這些案例都是巨大的 Python 代碼庫,但您必須懷疑:如果 Python 的高層人員從事此工作需要花費(fèi)這么長時(shí)間,那么對(duì)于一家公司非高層做決策來說可能要花費(fèi)更多的時(shí)間。
安全問題是一個(gè)很重要的考量問題
具有諷刺意味的是,您會(huì)認(rèn)為不升級(jí)將是更大的風(fēng)險(xiǎn)。但是在較大的組織中,不允許升級(jí) Python3:管理員或安全團(tuán)隊(duì)向他們推送更新。在某些情況下,也不允許下載更新 PIP。如果 Python 2 是安全團(tuán)隊(duì)同意的默認(rèn)協(xié)議,那么它可能需要做出巨大的努力才能說服人們將其切換到 3,尤其是在受到嚴(yán)格監(jiān)管(例如醫(yī)療保健或金融)和政府的 IT 環(huán)境中。
慣性
盡管許多版本的 Linux(例如 RHEL)在 Python 2 和 Python 3 之間都包括了 Python 3,但這絕不是默認(rèn)值,在 2 和 3 之間切換時(shí),經(jīng)常發(fā)現(xiàn)一些問題,尤其是指向系統(tǒng)版本的鏈接默認(rèn)使用 Python2。
Python 經(jīng)歷了從 2 到 3 的漫漫長路,個(gè)人和具有前瞻性的創(chuàng)業(yè)公司都采用了它?,F(xiàn)在,第二大遷移將發(fā)生在大型企業(yè)從 2 開始遷移的時(shí)候。關(guān)于 Python 2,我們將看到 2020 年 40%使用率的數(shù)量進(jìn)一步減少,但是變化將是遞增的。