“內(nèi)置電池”是 Python 最為顯著的特性之一,它提供了 200 多個開箱即用的標準庫。但是,歷經(jīng)了 30 多年的發(fā)展,很多標準庫已經(jīng)成為了不得不舍棄的歷史包袱,因為它們正在“漏電”!
創(chuàng)新互聯(lián)是一家專業(yè)提供豐順企業(yè)網(wǎng)站建設,專注與成都網(wǎng)站建設、成都做網(wǎng)站、成都h5網(wǎng)站建設、小程序制作等業(yè)務。10年已為豐順眾多企業(yè)、政府機構(gòu)等服務。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設公司優(yōu)惠進行中。
好消息是,Python 正在進行一場“瘦身手術”,詳情可查閱:
那么,我們會有這樣一個話題:當 Python 發(fā)布了一個新版本的時候,如何找出它比上一個版本(或者更早版本)增加或刪除了哪些標準庫呢?
比如,當 Python 發(fā)布 3.11.1 版本時,如何找出它相比于上一個版本(即 3.11.0),增刪了哪些標準庫呢?
也許你馬上就想到了一個辦法:查看官方的版本變更文檔啊~
沒錯,官方文檔里肯定包含了我們所需的變更信息,但是,每個版本的《What's New》里信息太多了,這種沒有特定目標的搜索,只會費時費力。
假如要跨多個版本進行比較的話,比如 3.12 與 3.10 間的差異、或者未來的 3.x 跟現(xiàn)在的 3.11 比較,這個方法就更不好用了吧!
在 3.10 版本之前,想要獲知標準庫的變化情況,確實不太方便。但是,自 3.10 起,Python 提供了一個非常便捷的方法:sys.stdlib_module_names
!
官方文檔的描述:
來源:https://docs.python.org/zh-cn/3/library/sys.html?#sys.stdlib_module_names
簡單查看下它的內(nèi)容:
如上可見,sys.stdlib_module_names
返回的是一個 frozenset 類型的對象,其元素是所有標準庫的名稱。
有了詳細的標準庫清單后,我們就可以通過以下的步驟,比較出不同 Python 版本間的差異啦:
(1)獲取舊版本的標準庫(比如 3.10.0),序列化后存儲到文件/數(shù)據(jù)庫中
>>> import sys
>>> import pickle
>>> with open("libs", "wb") as f:
... pickle.dump(sys.stdlib_module_names, f)
...
(2)獲取新版本的標準庫(比如 3.11.0),與舊版本的標準庫進行比較
>>> import sys
>>> import pickle
>>> with open("libs", "rb") as f:
... old_libs = pickle.load(f)
...
>>> sys.stdlib_module_names - old_libs
frozenset({'_typing', '_scproxy', '_tokenize', 'tomllib'})
>>> old_libs - sys.stdlib_module_names
frozenset({'binhex'})
從以上示例中,我們可以得知,3.11 相比于 3.10 增加了_typing
、_scproxy
、_tokenize
以及 tomllib
,同時它也減少了一個binhex
。
簡簡單單幾行代碼,這種方法比翻閱繁雜的文檔要便捷且準確得多了。
值得注意的是,sys.stdlib_module_names
是 3.10 版本的新特性,在它之前,有一個相似的sys.builtin_module_names
,但它返回的只是被解釋器使用到的內(nèi)置模塊:
那么,除了上文提到的獲知 Python 標準庫刪減情況的用途之外,這個新特性還有什么用處呢?換句話說,Python 官方為什么突然新增了sys.stdlib_module_names
這項功能呢?
原文鏈接:https://mp.weixin.qq.com/s/NoZniWQU3dUA_0TmZ2kHzw
其實,社區(qū)中有一個三方庫stdlib-list
,可用于獲取部分 Python 版本(2.6-2.7;3.2-3.9)的標準庫清單。這個庫的作者在文檔中提到了他的訴求,也提到其它開發(fā)者有著同樣的訴求:
開發(fā)了 sys.stdlib_module_names
這項功能的核心開發(fā)者 Victor Stinner 也總結(jié)了幾個使用場景:
當計算項目的依賴關系時,忽略標準庫中的模塊:https://github.com/jackmaney/pypt/issues/3
當監(jiān)測第三方代碼的執(zhí)行時,忽略標準庫,使用監(jiān)測工具的--ignore-module
選項:https://stackoverflow.com/questions//how-can-i-get-a-list-of-all-the-python-standard-library-modules
在格式化 Python 代碼文件時,對 import 的標準庫模塊進行分組。isort 庫包含了標準庫的列表,它依據(jù) Python 在線文檔生成了每個版本的標準庫清單:https://github.com/PyCQA/isort/tree/develop/isort/stdlibs
從這些使用場景來看,sys.stdlib_module_names
的作用還真是不小。另外,在寫作本文的時候,我從 CPython 的 Issue # 中發(fā)現(xiàn),著名的機器學習庫pytorch
也需要這項功能。
pytorch
曾經(jīng)硬編碼了每個 Python 版本的標準庫列表,代碼冗長,現(xiàn)在已經(jīng)適配成使用新的方法 ,大大方便了后續(xù)的維護:
11 月 15 日時,Python 3.12 alpha 2 版本發(fā)布了,這個版本開始移除大量過時的廢棄的內(nèi)容(標注庫、標準庫的子模塊、類和函數(shù)等)。感興趣的同學,可以用本文介紹的“冷知識”,去看看到底出現(xiàn)了哪些變化啦~
首發(fā)于 Python貓 ,如需轉(zhuǎn)載,請聯(lián)系作者
知乎:Python貓
博客園:豌豆花下貓
掘金:豌豆花下貓
CSDN:Python貓