精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

四年完成400萬行Python代碼檢查,甚至順手寫了個編譯器

新聞 前端
本文,Dropbox 公司完整輸出了從項目研究到實踐的 Python 靜態(tài)檢查全過程,以期對各位開發(fā)者有所幫助。

作為 Python 的大用戶之一,Dropbox 公司內(nèi)部聚集了數(shù)百萬行 Python 代碼,動態(tài)類型的存在讓代碼越來越難以理解。因此,公司開始利用 mypy 逐步將代碼轉(zhuǎn)換為靜態(tài)類型。雖然效果得到了充分驗證,但整個過程充滿了各種錯誤和失敗。

本文,Dropbox 公司完整輸出了從項目研究到實踐的 Python 靜態(tài)檢查全過程,以期對各位開發(fā)者有所幫助。

事實上,Python 已經(jīng)成為 Dropbox 公司使用范圍最廣的語言,其廣泛適用于后端服務(wù)與桌面客戶端應(yīng)用程序等(當(dāng)然,Dropbox 公司也在大量使用 Go、TypeScript 以及 Rust 等語言)。在 Dropbox 公司數(shù)以百萬計的 Python 代碼行中,動態(tài)類型的存在讓代碼越來越難以理解,并嚴(yán)重影響生產(chǎn)力水平。為了緩解這一問題,Dropbox 公司一直在利用 mypy 逐步將代碼轉(zhuǎn)換為靜態(tài)類型(順帶一提,mypy 可能是目前 Python 當(dāng)中最流行的獨立類型檢查器,屬于開源項目,其核心開發(fā)團(tuán)隊來自于 Dropbox。)。

截至目前,Dropbox 已經(jīng)在成千上萬個項目當(dāng)中使用 mypy,而且效果都得到了很好地驗證。但對于此次全方位檢查 Python 代碼,Dropbox 仍然抱著忐忑的心情,整個過程也充滿了錯誤與失敗。在今天的文章中,Dropbox 將向大家分享 Python 靜態(tài)檢查之旅——從最早的學(xué)術(shù)研究項目,到現(xiàn)在逐步讓類型檢查與類型提示成為 Python 社區(qū)中眾多開發(fā)人員的常規(guī)操作。現(xiàn)在,已經(jīng)有多種工具支持類型檢查功能,包括各類 IDE 與代碼分析器等。

為什么要進(jìn)行類型檢查?

如果開發(fā)者只使用過動態(tài)類型的 Python,當(dāng)然有可能對靜態(tài)類型以及 mypy 感到陌生。甚至,不少開發(fā)者就是因為動態(tài)類型而喜歡上 Python,但這事兒在邏輯上就有點莫名其妙。其關(guān)鍵應(yīng)該在于,靜態(tài)類型檢查是實現(xiàn)規(guī)模化的前提:項目越大,需要的靜態(tài)類型就越多。

一旦項目中包含成千上萬行代碼,而且有多位工程師在同時使用,以往開發(fā)經(jīng)驗告訴我們,理解代碼內(nèi)容就成了保障開發(fā)人員工作效率的關(guān)鍵所在。如果沒有類型注釋,基本的代碼作用推理(例如找到函數(shù)的有效參數(shù),或者可能的返回值類型)就會成為一大難題。以下是幾個在缺少類型注釋時,開發(fā)人員難以回答的典型問題: 

  • 這個函數(shù)能返回 None 嗎?
  • 這里的 items 參數(shù)是干什么用的?
  • id 屬性是什么類型:到底是 int、str、抑或是自定義類型?
  • 這個參數(shù)需要的是一份清單、一個元組還是一個組?

只要有了類型注釋,開發(fā)者能夠很輕松地回答這些與代碼片段相關(guān)的問題,例如:

  1. class Resource: 
  2. id: bytes 
  3. ... 
  4. def read_metadata(self, 
  5. items: Sequence[str]) -> Dict[str, MetadataItem]: 
  6. ... 
  • read_metadata 并不會返回 None,因為返回類型不是 Optional[…]
  • items 參數(shù)代表一系列字符串,其不可能隨意迭代。
  • id 屬性為字節(jié)字符串。

在理想情況下,我們當(dāng)然希望把這一切都記錄在文檔中,但擁有從業(yè)經(jīng)驗的開發(fā)者肯定知道沒這么好的事兒。即使存在此類文檔,我們也無法完全信任其中的內(nèi)容——例如內(nèi)容含糊不清或者不夠準(zhǔn)確,因此帶來巨大的誤解空間。對于大型團(tuán)隊或代碼庫,這類問題可能產(chǎn)生巨大的影響:

雖然 Python 在項目早期與中期階段表現(xiàn)良好,但當(dāng)項目發(fā)展到特定階段后,成功的項目與使用 Python 語言的企業(yè)可能面臨一個關(guān)鍵性決定:我們是否需要利用靜態(tài)類型語言重寫所有內(nèi)容? 

類似 mypy 這樣的類型檢查器主要負(fù)責(zé)提供用于類型描述的形式語言,并通過驗證所獲得的類型與實現(xiàn)(以及可能存在的可選項)間的匹配解決這一難題。更具體地講,類型檢查器專門提供經(jīng)過驗證的文檔。

當(dāng)然,除此之外,類型檢查器還可帶來其它助益: 

  • 類型檢查器能夠發(fā)現(xiàn)許多微妙(以及不那么微妙)的 bug。其中的典型例子,就是開發(fā)者忘記處理的 None 值或者其它一些特殊條件。
  • 重構(gòu)更簡單,因為類型檢查器通常能夠準(zhǔn)確告訴我們需要變更的代碼。我們不需要進(jìn)行 100% 全覆蓋測試,這本身也不具備可行性。另外,我們也不需要跟蹤深層堆棧以了解到底出了什么問題。
  • 即使是在大型項目中 ,mypy 也能夠在幾分之一秒內(nèi)完成完整的類型檢查。運(yùn)行測試通常需要幾十秒或者幾分鐘。類型檢查帶來的快速反饋,能夠幫助開發(fā)者更快實現(xiàn)迭代。這意味著不需要編寫脆弱且難以維護(hù)的單元測試,用以模擬及修復(fù)現(xiàn)有代碼以獲取快速反饋。
  • 以 PyCharm 以及 Visual Studio Code 為代表的 IDE 和編輯器可利用類型注釋實現(xiàn)代碼補(bǔ)全、高亮顯示錯誤并支持更好的定義功能——這里僅列出幾項典型的功能性應(yīng)用。對于一部分程序員而言,這些功能直接決定著他們的生產(chǎn)效率。這類用例不需要獨立的類型檢查工具。當(dāng)然,像 mypy 這樣的獨立工具仍有助于保證注釋與代碼之間的同步。

啟動遷移:性能成為瓶頸

在 Dropbox,我們成立了一個三人小隊,從 2015 年底開始研究 mypy。成員分別是 Guido、Greg Price 以及 David Fisher。從那時起,工作開始快速推進(jìn)。首先,在 mypy 采用面前的最大障礙就是性能。我們一直在將其運(yùn)行在 CPython 解釋器上,這對于 mypy 這樣的工具來說速度有點不夠用。(作為包含 JIT 編譯器的 Python 替代性方案,PyPy 在這方面也幫不上什么忙。)

幸運(yùn)的是,我們實現(xiàn)了一系列算法層面的改進(jìn)。我們采用的第一項加速措施就是 增量檢查。 其背后的思路非常簡單:如果模塊的所有依賴關(guān)系都與 mypy 運(yùn)行前的狀態(tài)毫無區(qū)別,那我們完全可以使用前一次運(yùn)行的緩存數(shù)據(jù)獲取依賴關(guān)系,意味著只需要類型檢查修改了的文件及其依賴關(guān)系。mypy 則在此基礎(chǔ)上更進(jìn)一步:如果模塊的外部接口沒有改變,mypy 甚至不需要重新檢查導(dǎo)入該模塊的其它模塊。

在對現(xiàn)有代碼進(jìn)行批量注釋時,增量檢查確實非常有用,因為其中往往涉及 mypy 的大量迭代運(yùn)行,用以處理陸續(xù)插入且逐漸細(xì)化的類型。最初的 mypy 運(yùn)行仍然相當(dāng)緩慢,這是因為它需要處理大量依賴項。為此,我們實現(xiàn)了遠(yuǎn)程緩存。如果 mypy 檢測到本地緩存可能已經(jīng)過期,mypy 將從集中存儲庫下載整個代碼庫的最新緩存快照。在此之后,它會以下載到的緩存為基礎(chǔ)執(zhí)行增量構(gòu)建。這又進(jìn)一步提高了性能表現(xiàn)。

到 2016 年底,Dropbox 公司已經(jīng)有大約 42 萬行 Python 完成了類型注釋。很多用戶都熱衷于類型檢查,而 mypy 的使用則在 Dropbox 各團(tuán)隊之間迅速傳播。

情況看起來相當(dāng)不錯,但距離真正的成功還有很長的路。我們開始定期進(jìn)行內(nèi)部用戶調(diào)查,借以找出痛點,并確定需要優(yōu)先考慮的工作(這種習(xí)慣直到今天也一直被保持下來)。其中,有兩項請求始終排名最高:更大的類型檢查覆蓋范圍以及更快的 mypy 運(yùn)行速度。 很明顯,我們的性能與采用提升工作還沒有全部完成。為此,我們還得在這兩項任務(wù)上再多下點力氣。

性能提升方法一:使用 mypy 守護(hù)進(jìn)程

增量構(gòu)建雖然提升了 mypy 的速度,但仍然沒有達(dá)到頂峰。大量增量運(yùn)行可能需要一分鐘的處理時長。對于任何面對大型 Python 代碼庫的用戶來講,其中的原因相信并不難理解:循環(huán)導(dǎo)入。

我們擁有數(shù)百個模塊,模塊相互間接導(dǎo)入。如果導(dǎo)入周期的任何文件發(fā)生變更,那么 mypy 就必須處理周期中的所有文件,同時還得處理在此周期內(nèi)導(dǎo)入該模塊的所有其它模塊。其中最臭名昭著的循環(huán)就是“糾結(jié)(tangle)”,它給 Dropbox 帶來了很大麻煩。其中一度包含有數(shù)百個模塊,眾多測試級乃至產(chǎn)品級功能都要或直接或間接地將其導(dǎo)入。

我們一直在考慮打理這種糾結(jié)無比的依賴關(guān)系,但卻始終沒有合適的方法著手進(jìn)行。畢竟我們不熟悉的代碼太多了。因此,我們想出了另一個辦法——即使存在這種“糾結(jié)”,我們同樣可以提升 mypy 速度。答案就是,使用 mypy 守護(hù)進(jìn)程。守護(hù)進(jìn)程是一項服務(wù)器進(jìn)程,負(fù)責(zé)執(zhí)行兩項非常重要的工作。

首先,它將關(guān)于整體代碼庫的信息保存在內(nèi)存中,這樣每次 mypy 運(yùn)行就不再需要加載數(shù)千條與所導(dǎo)入依賴項相對應(yīng)的緩存數(shù)據(jù)。其次,它會跟蹤函數(shù)與其構(gòu)造之間的細(xì)粒度依賴關(guān)系。例如,如果函數(shù) foo 調(diào)用函數(shù) bar,那么就存在一項從 bar 到 foo 的依賴關(guān)系。當(dāng)文件發(fā)生變更時,守護(hù)程序會首先單獨處理已經(jīng)變更的文件;接下來,它會查找該文件中包含的外部可見變更,例如變更的函數(shù)簽名。守護(hù)程序所采用的細(xì)粒度依賴項管理機(jī)制,能夠確保只重新檢查實際變更的那些函數(shù)——換言之,只檢查極少數(shù)函數(shù)。

實現(xiàn)上述目標(biāo)當(dāng)然是個巨大的挑戰(zhàn),因為我們最初的 mypy 實現(xiàn)方案只適合一次處理一個文件。但在實際需求發(fā)生變化之后——例如當(dāng)某個類獲得一個新的基類時,我們必須重新處理大量邊緣情況。經(jīng)過艱苦卓絕的努力與投入,我們成功將大部分增量運(yùn)行縮短至幾秒鐘。這是一場偉大的勝利,至少在我們當(dāng)事人看來相當(dāng)偉大!

性能提升方法二:將 Python 編譯為 C

配合之前提到的遠(yuǎn)程緩存,mypy 守護(hù)進(jìn)程幾乎完全解決了增量類用例,工程師們只需要對少量文件進(jìn)行迭代變更即可。但是,最差情況下的性能表現(xiàn)仍然遠(yuǎn)未達(dá)到最佳狀態(tài)。進(jìn)行一次徹底的 mypy build 可能需要 15 分鐘,這樣的結(jié)果當(dāng)然無法令人滿意。由于工程師們在不斷編寫新代碼,并在現(xiàn)有代碼當(dāng)中添加類型注釋,因此情況每周都在惡化。我們的用戶渴望獲得更高的性能,而我們也自然不能讓大家失望。

因此,我們決定延續(xù) mypy 立項之初的重要想法——將 Python 編譯為 C。 遺憾的是,Cython(一款現(xiàn)成的 Python 到 C 編譯器)并不能提供任何顯著的加速效果,因此 我們決定從零開始編寫編譯器。 由于 mypy 代碼庫(使用 Python 編寫)已經(jīng)全面完成類型注釋,因此利用這些注釋來加快速度自然是符合邏輯的選擇。我構(gòu)建了一套快速概念驗證原型,其在各類微基準(zhǔn)測試中將性能提升了 10 倍以上。我們的想法是將 Python 模塊編譯為 CPython C 擴(kuò)展模塊,并將類型注釋轉(zhuǎn)換為運(yùn)行時類型檢查(在運(yùn)行時中通常被忽略的類型注釋,僅供類型檢查器使用)。我們開始著手將 mypy 實現(xiàn)由 Python 遷移至真正的靜態(tài)類型語言,這恰好與 Python 的遷移思路完全匹配。(這種跨語言遷移正成為新的常態(tài),mypy 最初由 Alore 編寫,但后來則轉(zhuǎn)換為 Java/Python 自定義語法的混合體。)

對 CPython 擴(kuò)展 API 的定位,是保持項目整體可管理性的關(guān)鍵所在。我們不需要實現(xiàn)虛擬機(jī)或者 mypy 所需要的任何庫。此外,我們?nèi)匀豢梢岳靡磺性?Python 生態(tài)系統(tǒng)與工具(例如 pytest),并能夠在開發(fā)期間繼續(xù)使用經(jīng)過解釋的 Python 代碼,從而實現(xiàn)極快的編輯測試周期且不必等待編譯過程。

這款被我們命名為 mypyc 的編譯器(因為它利用 mypy 作為前端來執(zhí)行類型分析)非常成功。總體而言,我們在不使用緩存的前提下實現(xiàn)了大約 4 倍的運(yùn)行性能提升。mypyc 項目的核心開發(fā)在小團(tuán)隊的推動之下用了大約 4 個月即告完成,團(tuán)隊成員包括 Michael Sullivan、Ivan Levkivskyi、Hugh Han 和我自己。很明顯,這里的工作量遠(yuǎn)少于使用 C++ 或者 Go 完全重寫 mypy,相關(guān)影響也要小得多。我們希望 mypyc 最終能夠被交付至 Dropbox 的其他工程師手上,供他們編譯并加速自己的更多代碼。

在達(dá)成如此出色的性能提升效果的過程中,我們嘗試了不少有趣的性能工程方法。編譯器可以利用快速、低級 C 構(gòu)造實現(xiàn)眾多操作的加速。例如,對某個已編譯函數(shù)的調(diào)用會被翻譯成 C 函數(shù)調(diào)用,而后者要比調(diào)用解釋函數(shù)快得多。另外,某些操作(例如字典查找)仍然會回退至常規(guī)的 CPython C API 調(diào)用,從而略微提升編譯時的調(diào)用速度。總而言之,我們擺脫了解釋帶來的性能開銷,從而稍稍改善了操作的速度表現(xiàn)。

我們還進(jìn)行了一系列分析工作,希望了解“慢速操作”中的普遍共性。有了這些數(shù)據(jù),我們嘗試調(diào)整 mypyc 為這些操作生成速度更快的 C 代碼,或者利用更快的操作方式重寫相關(guān) Python 代碼(有時候確實沒什么好辦法,只能硬著頭皮重寫)。后者通常要比在編譯器中自動轉(zhuǎn)換容易得多,不過從長遠(yuǎn)來看,我們更傾向于實現(xiàn)自動化轉(zhuǎn)換。但還是要具體問題具體分析,有時候為了以最低的投入獲得更大的性能提升,我們也會抄近路。

實操:檢查 400 萬行代碼

在完成上述工作后,還面臨一個重要挑戰(zhàn)(也是 mypy 用戶調(diào)查中排名第二的重要要求)就是提升類型檢查的覆蓋范圍。 我們嘗試了多種方法以實現(xiàn)這項目標(biāo):從有機(jī)增長,到專注于 mypy 團(tuán)隊的手動調(diào)整,再到靜態(tài)與動態(tài)自動化類型推理等。最后,我們發(fā)現(xiàn)其中并不存在簡單的實現(xiàn)策略,但我們將多種方法結(jié)合起來,從而顯著提高了能夠在代碼庫中實現(xiàn)的快速注釋工作量。

結(jié)果就是,我們在最大的 Python 庫(后端代碼)中的注釋行數(shù)在大約三年之內(nèi)增長至近 400 萬行,這些全都遷移成了靜態(tài)類型代碼。mypy 現(xiàn)在支持多種覆蓋報告,能夠幫助我們輕松跟蹤相關(guān)進(jìn)度。具體來講,我們可以報告各類不夠明確的類型來源——例如在注釋中使用的顯式、未經(jīng)檢查的類型,或者未進(jìn)行類型注釋的已導(dǎo)入第三方庫等。為了在 Dropbox 當(dāng)中改善類型檢查精度,我們還在中央 Python 類型庫中為不少流行的開源庫提供經(jīng)過針對性改進(jìn)的類型定義(即 stub 文件)。

我們實現(xiàn)了(并在后續(xù) PEP 當(dāng)中標(biāo)準(zhǔn)化了)新的類型系統(tǒng),旨在為某些慣用的 Python 模式提供更精確的類型。其中一個典型例子正是 TypeDict,其負(fù)責(zé)提供 JSON 類字典類型。字典當(dāng)中包含一組固定的字符串鍵,各個字符串擁有不同的值類型。我們后續(xù)還將不斷擴(kuò)展這套類型系統(tǒng),同時考慮改進(jìn)對 Python 數(shù)字堆棧的支持能力。

四年完成400万行Python代码检查,甚至顺手写了个编译器

四年完成400万行Python代码检查,甚至顺手写了个编译器

四年完成400万行Python代码检查,甚至顺手写了个编译器

以下是 Dropbox 在提升注釋覆蓋率時,設(shè)定的核心工作要點: 

  • 嚴(yán)格性。逐漸增加了對新代碼的嚴(yán)格要求。我們先從較為簡單的角度入手,要求為原有文件補(bǔ)充注釋。現(xiàn)在,我們則要求在繼續(xù)補(bǔ)充注釋的同時,在新的 Python 文件中使用類型注釋。
  • 覆蓋率報告。我們每周都會向各團(tuán)隊發(fā)送電子郵件報告,旨在統(tǒng)計他們的注釋覆蓋率,并提供關(guān)于最有必要注釋的內(nèi)容的相關(guān)建議。
  • 外展。我們與各團(tuán)隊就 mypy 進(jìn)行交流,以幫助他們快速上手這款新工具。
  • 調(diào)查。我們定期進(jìn)行用戶調(diào)查以找到最重要的痛點,并竭盡全力解決這些問題(甚至可以發(fā)明一種新的語言來加快 mypy 的速度!)。
  • 性能。我們通過 mypy 守護(hù)程序與 mypyc 改進(jìn)了 mypy 性能(p75 獲得高達(dá) 44 倍的性能提升),從而減少注釋流程中的阻礙,并允許用戶根據(jù)需要擴(kuò)展類型檢查代碼庫的規(guī)模。
  • 編輯器集成。我們?yōu)?Dropbox 內(nèi)部流行的各款編輯器提供了 mypy 運(yùn)行集成,具體包括 PyCharm、Vim 以及 VS Code 等。這使得注釋迭代變得更輕松,也提升了大家為遺留代碼做注釋的熱情。
  • 靜態(tài)分析。我們編寫了一款利用靜態(tài)分析來推斷函數(shù)簽名的工具。雖然目前它只能處理非常簡單的場景,但仍然幫助我們快速提升了注釋覆蓋范圍。
  • 第三方庫支持。我們的不少代碼都用到了 SQLAlchemy,它使用的很多動態(tài) Python 函數(shù)無法由 PEP 484 類型進(jìn)行直接建模。為此,我們制作了一個 PEP 561 stub 文件包及一款開源 mypy 插件以提供支持。

經(jīng)驗總結(jié) 檢查 400 萬行代碼絕非易事,我們在整個過程中遇到不少挑戰(zhàn),當(dāng)然也犯過錯誤。下面,我想總結(jié)經(jīng)驗教訓(xùn),希望能給大家?guī)韱⑹尽?/p>

文件丟失。 起步之初,我們的 mypy 版本只需處理少量內(nèi)部文件——或者說,從未接觸過 build 之外的一切。在添加第一條注釋時,文件被隱式添加到 build 當(dāng)中。如果從 build 外部的模塊導(dǎo)入任何內(nèi)容,則會獲得 Any 類型的值——而這些值根本就不會被納入檢查范圍。這導(dǎo)致類型分析精度大打折扣,并在遷移早期給我們帶來了不少麻煩。雖然現(xiàn)在已經(jīng)解決了,而且也算是一種典型做法,但在最糟糕的情況下,如果兩個孤立的類型檢查機(jī)制被合并起來,而這兩種機(jī)制之間又互不兼容,那么我們就必須對注釋進(jìn)行大量更改!回想起來,我們應(yīng)該盡早將基礎(chǔ)庫模塊添加到 mypy build 中。

注釋遺留代碼。 在剛剛開始時,我們面對著超過 400 萬行的現(xiàn)有 Python 代碼。很明顯,對如此規(guī)模的代碼進(jìn)行注釋是項浩大的工程。我們編寫了一款名為 PyAnnotate 的工具,它能夠在運(yùn)行測試的同時收集類型,并根據(jù)類型結(jié)果插入類型注釋——但最終這款工具并沒能得到廣泛采用。理由很簡單:收集類型的速度很慢,而生成的類型通常也需要大量人為調(diào)整。我們也考慮過在每一次 build 測試時對一小部分實時網(wǎng)絡(luò)請求自動運(yùn)行這款工具,但考慮到這兩種方式都可能帶來較大風(fēng)險,最終只能作罷。

大多數(shù)代碼都是由代碼所有者手動注釋。 我們提供關(guān)于高價值模塊與函數(shù)的報告,以幫助簡化注釋流程。那些在數(shù)百個位置使用的庫模塊,自然是注釋工作中的優(yōu)先考量對象;正在被替換的遺留服務(wù)同樣值得關(guān)注。此外,我們還嘗試?yán)渺o態(tài)分析為遺留代碼生成靜態(tài)注釋。

導(dǎo)入周期。 導(dǎo)入周期(也就是「tangle」或者說糾結(jié)周期)的存在令 mypy 提速變得非常困難。我們還需要努力讓 mypy 支持來自導(dǎo)入周期的各種習(xí)慣。我們最近剛剛完成了一個重大項目的重新設(shè)計,最終解決了大多數(shù)導(dǎo)入周期問題。這些解決方案實際上源自項目早期研究中使用的 Alore 語言。Alore 的語法使得導(dǎo)入周期的處理變得更輕松。當(dāng)然,我們也在這種簡單的實現(xiàn)中繼承了某些限制因素(對 Alore 來說倒不是什么問題)。Python 之所以很難搞定導(dǎo)入周期,是因為其語句當(dāng)中可能指代多種事物。例如,賦值可能實際上定義了一個類型別名,而且 mypy 在大部分導(dǎo)入周期處理完成之后一直無法檢測到該類型。Alore 就不存在這種模糊性。總之,有些早期設(shè)計中不經(jīng)意做出的決定,很可能成為多年之后的痛苦根源!

結(jié)束語

從早期原型設(shè)計到如今對 400 萬行代碼進(jìn)行類型檢查,這是一段漫長的旅程。在過程當(dāng)中,我們對 Python 的類型提示進(jìn)行了標(biāo)準(zhǔn)化,建立起圍繞 Python 類型檢查發(fā)展出的新興生態(tài)系統(tǒng)、為 IDE 與編輯器開發(fā)出類型提示支持機(jī)制,在多種類型檢查器之間進(jìn)行功能權(quán)衡并實現(xiàn)了庫支持能力。

雖然在 Dropbox 公司內(nèi)部,類型檢查已經(jīng)被視為一項必要工作,但我相信就整個社區(qū)而言,對 Python 代碼進(jìn)行類型檢查仍是種新生事物。當(dāng)然,我也堅信這種好習(xí)慣將不斷推廣并給更多人帶來助益。如果大家還沒有在自己的大型 Python 項目中使用類型檢查,那么現(xiàn)在就是最好的時機(jī)——根據(jù)我的交流整理,所有嘗試類型檢查的開發(fā)者都后悔沒有早點參與。總而言之,類型檢查正幫助 Python 成長為一款更適合大型項目的出色語言。

原文鏈接:https://blogs.dropbox.com/tech/2019/09/our-journey-to-type-checking-4-million-lines-of-python/ 

 

責(zé)任編輯:張燕妮 來源: AI前線
相關(guān)推薦

2017-03-23 14:07:55

代碼程序員

2021-03-02 13:56:24

Linux 5.12代碼驅(qū)動

2019-01-03 09:29:15

Linux 系統(tǒng) 數(shù)據(jù)

2020-04-02 15:39:51

代碼編譯器前端

2012-07-23 09:58:50

代碼程序員

2020-02-24 16:27:19

開源大數(shù)據(jù)計算引擎

2009-07-21 08:44:14

微軟Linux內(nèi)核開源操作系統(tǒng)

2018-06-07 16:20:56

代碼代碼質(zhì)量程序員

2022-09-05 10:03:55

MypyPython代碼

2015-09-01 16:26:18

Linux內(nèi)核

2010-01-11 15:47:37

C++編譯

2023-08-31 11:13:51

物聯(lián)網(wǎng)IOT

2023-08-28 10:28:18

5G物聯(lián)網(wǎng)

2012-04-05 09:13:17

C代碼

2009-07-21 08:51:33

微軟發(fā)布Linux設(shè)備微軟開源虛擬化

2011-05-03 09:10:12

項目管理程序員

2024-03-13 15:48:43

2009-08-20 16:34:50

Linux源代碼紅帽Linux內(nèi)核

2018-10-15 09:20:08

代碼軟件工程師

2023-06-28 14:18:06

點贊
收藏

51CTO技術(shù)棧公眾號

欧美成年黄网站色视频| 国产精品6666| 99视频这里有精品| 亚洲卡通欧美制服中文| 国产精品毛片va一区二区三区| 日本中文字幕网| 精品久久美女| 宅男噜噜噜66一区二区66| www.国产在线播放| 久蕉在线视频| 国产一区二区视频在线播放| 91国在线精品国内播放| 色欲狠狠躁天天躁无码中文字幕 | 日韩欧美xxxx| av在线导航| 久久久久久**毛片大全| 成人黄色午夜影院| 性无码专区无码| 亚洲一级毛片| 国产一区二区三区毛片| 国产精品果冻传媒| 91丨精品丨国产| 色哟哟欧美精品| 欧美亚洲色图视频| 1区2区3区在线观看| 91女神在线视频| 91免费视频国产| а中文在线天堂| 影音先锋亚洲电影| 伦理中文字幕亚洲| 91麻豆精品国产91久久综合| 美国十次av导航亚洲入口| 3d动漫精品啪啪| 亚洲性生活网站| 黄色在线观看www| 亚洲精品久久久蜜桃| 亚洲砖区区免费| 狠狠v欧美ⅴ日韩v亚洲v大胸| 懂色一区二区三区免费观看| 国产精品欧美久久久| 国产成人一区二区三区影院在线| 欧美成人嫩草网站| 色妞一区二区三区| 日本理论中文字幕| 综合综合综合综合综合网| 精品1区2区在线观看| 国产精品久久久久久久av福利| 美女福利一区二区| 欧美日韩国产精品一区| 拔插拔插海外华人免费| 欧美午夜大胆人体| 亚洲免费在线视频一区 二区| 亚洲精品久久区二区三区蜜桃臀 | 99久久久无码国产精品| 国产乱码精品一区二区三区不卡| av一级黄色片| 国产一区二区三区精品欧美日韩一区二区三区 | 91精品婷婷国产综合久久性色| 能在线观看的av网站| 无码小电影在线观看网站免费 | 色噜噜狠狠色综合网图区| 国产伦精品一区二区三区视频女| 久草成人资源| 这里精品视频免费| 亚洲黄色网址大全| 成人羞羞动漫| 中文字幕国内精品| 美国美女黄色片| 色综合久久网| 日日噜噜噜夜夜爽亚洲精品| 亚洲一区电影在线观看| 欧美在线视屏| 欧美极品美女视频网站在线观看免费| 久久久久免费看| 99精品久久久| 国产91精品网站| 中文在线免费观看| 麻豆国产精品官网| 99视频免费观看蜜桃视频| 风流老熟女一区二区三区| www.视频一区| 欧美日韩另类综合| 麻豆传媒在线完整视频| 亚洲黄色性网站| www.av中文字幕| 姬川优奈av一区二区在线电影| 欧美性色黄大片| 国产精品999.| 精品淫伦v久久水蜜桃| 亚洲嫩模很污视频| 日本不卡一区视频| 国产精品sm| 人人澡人人澡人人看欧美| 国产精品露脸视频| 国产精品一区二区免费不卡| 精品免费国产| 色欧美激情视频在线| 亚洲蜜臀av乱码久久精品蜜桃| 日韩中字在线观看| 福利一区二区| 精品成a人在线观看| 国产熟妇久久777777| 外国成人免费视频| 97香蕉超级碰碰久久免费软件 | 1区2区在线| 在线观看日韩一区| 日本成人在线免费| 精品香蕉视频| 久久久久久久久久久av| 日本一区二区三区久久| 成人不卡免费av| 亚洲欧美在线网| 韩国成人二区| 日韩视频一区二区三区| 黄色片网站免费| 激情婷婷欧美| 91精品久久久久久综合乱菊| 亚洲区小说区图片区| 亚洲色图在线视频| 亚洲爆乳无码专区| 成人av地址| 久久影院在线观看| 最近中文字幕免费在线观看| k8久久久一区二区三区| 老汉色影院首页| a成人v在线| 精品视频在线导航| 久草网站在线观看| 久久国产精品99久久人人澡| 欧美xxxx黑人又粗又长精品| 免费男女羞羞的视频网站在线观看 | ijzzijzzij亚洲大全| 亚洲四虎影院| 国产视频精品久久久| 国产精品成人久久| 国产一区二区导航在线播放| 视频一区视频二区视频| 国模冰冰炮一区二区| 亚洲国产精品成人av| 欧美黄色免费看| 韩国女主播成人在线| 翔田千里亚洲一二三区| 亚洲承认视频| 亚洲石原莉奈一区二区在线观看| 性无码专区无码| 91论坛在线播放| 日本www在线视频| 福利欧美精品在线| 欧美激情精品在线| 99re只有精品| 亚洲精品中文在线影院| 日韩不卡的av| 欧美午夜一区| 国产欧美一区二区在线播放| wwww在线观看免费视频| 精品国产免费一区二区三区香蕉 | 91在线看片| 欧美视频一区在线| 91免费在线看片| 精品一区二区三区香蕉蜜桃| 天天综合五月天| 日韩在线观看一区二区三区| 色综合久综合久久综合久鬼88| 国产视频精品一区二区三区| 日韩av影视大全| 香蕉久久网站| 91精品久久久久久久久久入口| 美女国产在线| 日韩一区二区视频在线观看| 国产 日韩 欧美 成人| av色综合久久天堂av综合| 国产69精品久久久久久久| 亚洲黄页网站| 国产精品视频一| 中中文字幕av在线| 亚洲国产99精品国自产| 9i看片成人免费看片| 中文欧美字幕免费| 熟妇无码乱子成人精品| 亚洲精品偷拍| 日韩激情视频| 精品国模一区二区三区欧美| 国内揄拍国内精品| 风间由美一区| 日韩色视频在线观看| 久久久精品免费看| 国产精品免费网站在线观看| 伦伦影院午夜理论片| 亚洲狼人精品一区二区三区| 日韩女优中文字幕| 精品国产鲁一鲁****| 97视频色精品| 秋霞成人影院| 亚洲精品成人网| 一级做a爱片性色毛片| 亚洲自拍另类综合| 日本二区在线观看| 丁香网亚洲国际| 超碰在线97免费| 亚洲午夜久久久久久尤物| 欧美最大成人综合网| 久久久久久亚洲精品美女| 亲爱的老师9免费观看全集电视剧| 亚洲精品传媒| 日韩精品中文字幕视频在线| 99热这里只有精品9| 欧美性猛交xxxx乱大交3| 91插插插插插插| 国产亚洲精品bt天堂精选| 欧美xxxx日本和非洲| 美女网站视频久久| 亚洲精品国产拍免费91在线| 亚洲熟妇无码另类久久久| 久久av综合| 国产精品综合久久久久久| 韩国精品视频在线观看 | 日韩欧美三级一区二区| 盗摄牛牛av影视一区二区| 成人午夜黄色影院| 欧美黑人粗大| 久久噜噜噜精品国产亚洲综合| 中文字幕在线观看日本| 国产丝袜一区二区三区免费视频| 精品国产99久久久久久宅男i| 色哟哟精品一区| 日本视频免费在线| 亚洲午夜精品久久久久久久久| 三级黄色在线观看| 国产亚洲欧洲一区高清在线观看| 午夜不卡久久精品无码免费| 国产精品18久久久久久久久久久久 | 日本一区不卡| 亚洲精品白浆高清| 国内精品视频免费| 爱爱精品视频| 99精品99久久久久久宅男| 亚洲国产精选| 国产噜噜噜噜噜久久久久久久久| 韩国精品主播一区二区在线观看 | 国产亚洲观看| 国产一区在线播放| 久久女人天堂| 国产美女精品视频免费观看| 成人黄色视屏网站| 国产精品手机播放| 国产极品久久久久久久久波多结野| 日韩av片永久免费网站| 中文在线а√天堂| 国产99久久精品一区二区 夜夜躁日日躁 | 日本一区二区不卡| av日韩电影| 国产成人精品日本亚洲| 春暖花开亚洲一区二区三区| 国产精品久久久| 成人免费黄色| 成人激情视频在线播放| 精品国产乱码一区二区三区| 91av一区二区三区| jazzjazz国产精品久久| 国产欧美一区二区三区不卡高清| 欧美自拍一区| 老牛影视免费一区二区| 国产99久久久国产精品成人免费 | 国产福利在线观看| 在线视频一区二区| 色开心亚洲综合| 久久99青青精品免费观看| 俺来也官网欧美久久精品| 2021国产精品视频| 国产成人精品123区免费视频| 国产欧美日韩专区发布| 蜜桃精品视频| 精品国产一二| 成人a'v在线播放| 特色特色大片在线| 亚洲另类黄色| 中文久久久久久| 国产精品一区二区在线看| 四虎成人免费视频| 国产日韩欧美精品综合| 神马午夜精品91| 亚洲va欧美va国产va天堂影院| 国产91精品一区| 欧美日韩情趣电影| 性欧美8khd高清极品| 日韩精品中文在线观看| 精品麻豆一区二区三区| 97在线视频免费观看| 成人看片网站| 91九色偷拍| 色天天色综合| 一区二区三区av| 亚洲黄色高清| 中文字幕中文在线| 97se亚洲国产综合自在线不卡| 18精品爽国产三级网站| 亚洲一区二区三区国产| 精品一区二三区| 精品国产一区二区亚洲人成毛片| 久青青在线观看视频国产| 久久夜精品va视频免费观看| a日韩av网址| 91青青草免费在线看| 国产一区二区欧美| bt天堂新版中文在线地址| 美女www一区二区| 疯狂揉花蒂控制高潮h| 亚洲国产成人午夜在线一区 | 天堂地址在线www| 97视频在线免费观看| 国产不卡精品| 日本精品免费| 亚洲精品美女91| 国产伦精品一区二区三区妓女下载| 国产欧美日韩另类视频免费观看| 国产无精乱码一区二区三区| 欧美精品亚洲一区二区在线播放| 青青久在线视频| 欧美精品久久久久久久| 国产精品伦一区二区| 蜜桃麻豆91| 一区二区视频欧美| 日韩精品视频网址| 国产精品久久久久久久蜜臀| 久久一区二区三区视频| 精品久久久久av影院| 国产成人在线视频免费观看| 国产精品男人的天堂| 欧美猛男做受videos| 国产午夜福利视频在线观看| 成人av资源在线观看| 免费人成年激情视频在线观看| 欧美喷潮久久久xxxxx| 国产高清视频在线| 国产激情视频一区| 亚洲激情77| 日韩视频第二页| av一本久道久久综合久久鬼色| 免费视频网站www| 欧美一区二区三区小说| 黄色网址视频在线观看| 91精品国产综合久久香蕉922| 凹凸成人精品亚洲精品密奴| 日韩精品一区二区三区不卡| 26uuu另类欧美亚洲曰本| 四虎成人精品永久免费av| 欧美精品一区二区三区视频 | 国产精品久久久久久| 岛国av在线免费| 国产精品福利一区| 91国产精品一区| 久久综合久久八八| 精品中文在线| 亚洲激情免费视频| 国产精品羞羞答答xxdd| 欧美被狂躁喷白浆精品| 欧美成人精品3d动漫h| 男人天堂亚洲| 久草精品电影| 久久欧美肥婆一二区| 中文字幕第24页| 欧美久久一二区| 欧美人与性动交α欧美精品济南到| 国产精品免费一区二区| 国产欧美大片| 人人妻人人澡人人爽| 欧美精品vⅰdeose4hd| av在线免费网站| 国产视频一区二区三区四区| 国产一区二区三区的电影| 国产小视频自拍| 欧美日韩国产中文| 18加网站在线| 久久99导航| 男男视频亚洲欧美| 青青草手机在线视频| 亚洲精品理论电影| jvid一区二区三区| 久久免费一级片| 91在线看国产| 中国一区二区视频| 欧美国产视频日韩| 女优一区二区三区| 亚洲另类第一页| 亚洲成人精品在线观看| 国产露出视频在线观看| 91免费福利视频| 99国产精品99久久久久久粉嫩| 人妻一区二区视频| 欧美一区二区在线观看| 日韩激情电影| 亚洲最新免费视频| 9久草视频在线视频精品| 中文字幕福利视频| 欧美激情在线观看| 久久五月天小说| 中文字幕 日本| 欧美电影一区二区| 亚洲最新无码中文字幕久久| 精品日韩在线播放|