●在介紹Python的一些強大特性時,人們常常編造一些示例,以孤立的示例解釋各種特性。通過設計并構(gòu)建真實的應用程序,從設計原型一直演示到開發(fā)出符合生產(chǎn)質(zhì)量要求的應用程序,整個過程不只讓你了解各種特性如何工作,還會讓你看到它們?nèi)绾巫鳛楦蟮南到y(tǒng)設計過程的組成部分集成起來。另外,本書還會提供一些有用的注意項,并推薦一些庫,這些內(nèi)容是Python大會問答環(huán)節(jié)的主要關(guān)注點。本書還會討論現(xiàn)代Python開發(fā)的實踐和技術(shù),幫助你編寫清晰的、易于維護的代碼。
●本書針對的是已經(jīng)能夠使用Python編寫簡單程序但想要理解什么時候適合使用高級特性的開發(fā)人員,讓他們能夠自如地使用這些高級特性。想要提升自身Python編程水平以及已經(jīng)具有豐富的經(jīng)驗但希望了解新版本Python特性的開發(fā)人員,都特別適合閱讀本書。
【本書內(nèi)容】
本書精心挑選了主題,旨在介紹Python編程的各個不同方面。Python社區(qū)作為一個整體沒有充分理解或者利用這些方面,而且在指導新人時,不會把它們理所當然地教給新人。這并不是說這些特性一定很復雜,或者很難理解(當然有些特性確實如此),我相信,所有程序員都應該熟悉這些特性,即使他們并不會用到這些特性。
●第1章將介紹使用Python編寫簡單程序的不同方式,還會介紹Jupyter記事本以及Python調(diào)試器的用法。雖然這兩者都是相對來說為人熟知的工具,但很多人只熟悉其中的一個工具,而不是兩者都能夠熟練使用。本章還會介紹編寫命令行接口的不同方式,以及一些有用的第三方庫,它們支持簡潔的命令行工具開發(fā)。
●第2章將介紹幫助識別代碼中的錯誤的工具,例如自動測試和linting工具。無論是編寫大型代碼庫、很少需要編輯的代碼庫,還是要吸收第三方貢獻的代碼庫,這些工具都能夠讓你更容易地寫出讓自己有信心的代碼。這里介紹的工具都是我推薦的工具,但是,本章的關(guān)注點是理解它們的優(yōu)缺點。你可能已經(jīng)使用過其中的一個或多個工具,并且對于是否適合使用它們有自己的觀點。本章將幫助你理解權(quán)衡點,從而做出明智的決定。
●第3章將介紹Python中的代碼打包和依賴項分發(fā)。對于編寫可分發(fā)給其他人的應用程序,以及設計能夠可靠工作的部署系統(tǒng)來說,這些都是重要的功能。我們將使用這些功能,把獨立的腳本轉(zhuǎn)換為可安裝的應用程序。
●第4章將介紹插件架構(gòu)。這是一種強大的功能。經(jīng)常可以看到學習插件架構(gòu)的人使用它,這導致講解Python的人們對于是否講解插件架構(gòu)持謹慎態(tài)度。對于我們的示例,插件架構(gòu)十分適用。本章還將介紹一些用于命令行工具的高級技術(shù),它們能夠讓調(diào)試基于插件的系統(tǒng)變得更加容易。
●第5章將介紹Web接口和編寫復雜函數(shù)的技術(shù),如裝飾器和閉包。這些技術(shù)在Python中已經(jīng)是習語,但在其他許多編程語言中很難表達。本章還將介紹如何恰當?shù)厥褂贸橄蠡悺H藗兂32唤ㄗh使用抽象基類,因為學習抽象基類的人傾向于到處使用它們。在特定場景中,有節(jié)制地使用抽象基類是有優(yōu)勢的,當把抽象基類與第2章介紹的一些工具結(jié)合使用時更是如此。
●第6章將用另一個重要組件擴展我們的示例,這個組件就是收集數(shù)據(jù)的聚合服務器。本章還將演示Python程序員會用到的一些重要的第三方庫,例如requests庫。
●第7章將介紹Python中的線程和異步編程。線程常常會導致難以探查的bug。異步代碼能夠用于類似的任務,但許多Python程序員還沒有使用過這種習語,因為使用異步編程時,程序的行為與同步編程有很大區(qū)別。本章重點討論在真實場景中如何使用并發(fā)來實現(xiàn)某個結(jié)果,而不只是演示一個簡單的示例,或者演示異步編程的局限性。本章旨在得到能夠在真實場景中使用的代碼,并讓你徹底理解權(quán)衡點,而不是進行獨立的技術(shù)演示。
●第8章將更加深入地介紹異步編程,講解異步代碼的測試以及一些第三方庫。使用這些庫能夠編寫在異步上下文中處理外部工具(如數(shù)據(jù)庫)的代碼。本章還將簡要地介紹一些可以用來編寫出色API的高級技術(shù),例如上下文管理器和上下文變量,它們對于異步編程很有幫助。
●第9章返回Jupyter,使用它的一些功能來實現(xiàn)數(shù)據(jù)可視化和方便的用戶交互。我們將介紹如何在Jupyter記事本中把異步代碼用于小部件,還將介紹迭代器的高級用法和實現(xiàn)復雜數(shù)據(jù)類型的多種方式。
●第10章將詳細介紹如何讓Python代碼運行得更快,如何使用不同類型的緩存,以及這些緩存適用的場景。本章還將介紹如何對應用程序中的各個Python函數(shù)進行基準測試,以及如何解讀結(jié)果以找出速度緩慢的原因。
●第11章將擴展本書前面介紹過的一些概念,以更加優(yōu)雅地處理錯誤。我們將介紹如何修改插件架構(gòu),以便無縫地處理錯誤,同時保留完整的向后兼容性,還將深入介紹如何設計在遇到錯誤時就處理錯誤的過程。
●第12章將使用Python的迭代器和協(xié)程來增強我們開發(fā)的儀表板,為它們添加一些功能,這些功能不是實現(xiàn)被動的數(shù)據(jù)收集,而是主動檢查收集到的數(shù)據(jù),從而允許我們構(gòu)建包含多個步驟的分析流。
●本書按照構(gòu)建一個真實軟件的順序,通過一個貫穿全書的示例,解釋其他教程中一般不會講解的各種Python語言特性:從利用入口點讓可重用的控制臺腳本成為微服務,一直到高效使用asyncio整理來自多個數(shù)據(jù)源的數(shù)據(jù)。在此過程中,本書將介紹基于類型提示的linting、低開銷的測試,以及其他自動執(zhí)行的質(zhì)量檢查,以演示真實的開發(fā)過程。
●通過閱讀本書,你將了解以下內(nèi)容:
Python異步編程。
插件架構(gòu)。
如何使用類型注解。
Python相關(guān)測試技術(shù)。
打包和依賴項管理。
●具體而言:
第1章和第2章介紹開發(fā)環(huán)境和相關(guān)的工具;
第3~6章涵蓋代碼打包和依賴項分發(fā)、插件架構(gòu)、接口、聚合服務器等實用內(nèi)容;
第7章與第8章討論線程和異步編程相關(guān)內(nèi)容,以及一些高級主題;
第9~12章涉及可視化、調(diào)優(yōu)、錯誤處理以及數(shù)據(jù)分析相關(guān)主題。
●本書提供示例代碼下載,讀者可訪問本書GitHub頁面https://github.com/MatthewWilkes/advanced-python-development.git,簽出Git存儲庫并按照本書內(nèi)容一步步學習。
Python是一門非常成功的編程語言,自問世以來的30多年間,得到了非常廣泛的應用。主流操作系統(tǒng)默認提供Python,世界上的一些大型網(wǎng)站使用Python開發(fā)后臺,科學家常使用Python來拓展新知識。因為這么多人每天都在使用Python,所以Python的改進會快速、大量地出現(xiàn)。并不是每個Python開發(fā)人員都有機會參加會議,或者有時間關(guān)注社區(qū)不同部分所做的工作,所以Python語言及其生態(tài)系統(tǒng)的一些功能難免沒有得到它們應得的關(guān)注。
本書的目標是介紹Python語言及其工具中并不是每個人都知道的部分。如果你是一名經(jīng)驗豐富的開發(fā)人員,則很可能已經(jīng)知道了本書要介紹的許多工具,但可能也有很多是你想要使用卻沒有時間了解的工具。如果你負責維護一個已建成的穩(wěn)定系統(tǒng),就更可能遇到這種情況,因為對于這樣的系統(tǒng),無法頻繁地通過重構(gòu)組件來利用新的語言特性。
如果你使用Python的時間較短,則可能更加熟悉該語言近期新增的特性,但不會很熟悉廣闊生態(tài)系統(tǒng)中的一些可用的庫。參加一些活動(如Python會議)的一大好處是有機會注意到其他程序員帶來的質(zhì)量改進,并把它們集成到自己的工作流中。
本書并不是一本用獨立小節(jié)介紹Python不同特性的參考書。相反,本書是按照構(gòu)建一個真實軟件的方式來組織各個章節(jié)的。
許多技術(shù)文檔傾向于提供簡單的示例。簡單的示例很適合解釋某個特性的工作方式,但是對于理解什么時候使用這種特性沒有太大幫助。而且,也很難把簡單的示例作為基礎來構(gòu)建軟件,因為復雜代碼的架構(gòu)方式與簡單代碼有很大的區(qū)別。
通過使用這個示例,我們能夠在具體的上下文中思考技術(shù)選擇。你將了解在判斷某個方法是否合適時,需要記住哪些考慮因素。使用方式彼此相關(guān)的主題將被放到一起進行介紹,而不是把工作方式相關(guān)的主題放到一起進行介紹。
【關(guān)于本書】
我撰寫本書的目的,是分享我從社區(qū)不同地方學到的知識,以及我在超過15年的時間中編寫Python代碼所積累的經(jīng)驗。本書可以幫助你利用核心語言和增件庫來提高生產(chǎn)效率。你將學習如何使用異步編程、打包和測試等語言特性來成為一名高效的程序員,盡管嚴格來說,作為一名程序員,并非必須使用它們。
但是,本書的目標讀者是那些想要編寫代碼的人,而不是想要理解深層原理的人。我不會深入介紹涉及Python實現(xiàn)細節(jié)的主題。你不需要grokPython C擴展、元類或算法,就可以通過閱讀本書獲益。
重要的代碼示例用編號的代碼清單展示,本書配套代碼包含這些代碼清單的電子版。其中一些代碼清單下面還直接顯示了輸出,而不是用編號圖的方式單獨顯示輸出。
在本書的配套代碼中,還可以找到示例項目的代碼庫的完整版本,以及幫助完成練習的代碼?偟膩碚f,我建議你從https://github.com/Apress/advanced-python-development簽出Git存儲庫,然后切換到你正在閱讀的章節(jié)的相關(guān)分支,一步步學習代碼。
除了代碼清單,本書還展示了一些控制臺會話。當格式上類似于代碼的行以>開頭時,說明顯示的是一個shell會話。這些部分包括需要從操作系統(tǒng)的終端運行的命令。包含>>>的行演示的是Python控制臺會話,應該從Python解釋器運行。
【本書內(nèi)容】
本書精心挑選了主題,旨在介紹Python編程的各個不同方面。Python社區(qū)作為一個整體沒有充分理解或者利用這些方面,而且在指導新人時,不會把它們理所當然地教給新人。這并不是說這些特性一定很復雜,或者很難理解(當然有些特性確實如此),我相信,所有程序員都應該熟悉這些特性,即使他們并不會用到這些特性。
●第1章將介紹使用Python編寫簡單程序的不同方式,還會介紹Jupyter記事本以及Python調(diào)試器的用法。雖然這兩者都是相對來說為人熟知的工具,但很多人只熟悉其中的一個工具,而不是兩者都能夠熟練使用。本章還會介紹編寫命令行接口的不同方式,以及一些有用的第三方庫,它們支持簡潔的命令行工具開發(fā)。
●第2章將介紹幫助識別代碼中的錯誤的工具,例如自動測試和linting工具。無論是編寫大型代碼庫、很少需要編輯的代碼庫,還是要吸收第三方貢獻的代碼庫,這些工具都能夠讓你更容易地寫出讓自己有信心的代碼。這里介紹的工具都是我推薦的工具,但是,本章的關(guān)注點是理解它們的優(yōu)缺點。你可能已經(jīng)使用過其中的一個或多個工具,并且對于是否適合使用它們有自己的觀點。本章將幫助你理解權(quán)衡點,從而做出明智的決定。
●第3章將介紹Python中的代碼打包和依賴項分發(fā)。對于編寫可分發(fā)給其他人的應用程序,以及設計能夠可靠工作的部署系統(tǒng)來說,這些都是重要的功能。我們將使用這些功能,把獨立的腳本轉(zhuǎn)換為可安裝的應用程序。
●第4章將介紹插件架構(gòu)。這是一種強大的功能。經(jīng)?梢钥吹綄W習插件架構(gòu)的人使用它,這導致講解Python的人們對于是否講解插件架構(gòu)持謹慎態(tài)度。對于我們的示例,插件架構(gòu)十分適用。本章還將介紹一些用于命令行工具的高級技術(shù),它們能夠讓調(diào)試基于插件的系統(tǒng)變得更加容易。
●第5章將介紹Web接口和編寫復雜函數(shù)的技術(shù),如裝飾器和閉包。這些技術(shù)在Python中已經(jīng)是習語,但在其他許多編程語言中很難表達。本章還將介紹如何恰當?shù)厥褂贸橄蠡。人們常常不建議使用抽象基類,因為學習抽象基類的人傾向于到處使用它們。在特定場景中,有節(jié)制地使用抽象基類是有優(yōu)勢的,當把抽象基類與第2章介紹的一些工具結(jié)合使用時更是如此。
●第6章將用另一個重要組件擴展我們的示例,這個組件就是收集數(shù)據(jù)的聚合服務器。本章還將演示Python程序員會用到的一些重要的第三方庫,例如requests庫。
●第7章將介紹Python中的線程和異步編程。線程常常會導致難以探查的bug。異步代碼能夠用于類似的任務,但許多Python程序員還沒有使用過這種習語,因為使用異步編程時,程序的行為與同步編程有很大區(qū)別。本章重點討論在真實場景中如何使用并發(fā)來實現(xiàn)某個結(jié)果,而不只是演示一個簡單的示例,或者演示異步編程的局限性。本章旨在得到能夠在真實場景中使用的代碼,并讓你徹底理解權(quán)衡點,而不是進行獨立的技術(shù)演示。
●第8章將更加深入地介紹異步編程,講解異步代碼的測試以及一些第三方庫。使用這些庫能夠編寫在異步上下文中處理外部工具(如數(shù)據(jù)庫)的代碼。本章還將簡要地介紹一些可以用來編寫出色API的高級技術(shù),例如上下文管理器和上下文變量,它們對于異步編程很有幫助。
●第9章返回Jupyter,使用它的一些功能來實現(xiàn)數(shù)據(jù)可視化和方便的用戶交互。我們將介紹如何在Jupyter記事本中把異步代碼用于小部件,還將介紹迭代器的高級用法和實現(xiàn)復雜數(shù)據(jù)類型的多種方式。
●第10章將詳細介紹如何讓Python代碼運行得更快,如何使用不同類型的緩存,以及這些緩存適用的場景。本章還將介紹如何對應用程序中的各個Python函數(shù)進行基準測試,以及如何解讀結(jié)果以找出速度緩慢的原因。
●第11章將擴展本書前面介紹過的一些概念,以更加優(yōu)雅地處理錯誤。我們將介紹如何修改插件架構(gòu),以便無縫地處理錯誤,同時保留完整的向后兼容性,還將深入介紹如何設計在遇到錯誤時就處理錯誤的過程。
●第12章將使用Python的迭代器和協(xié)程來增強我們開發(fā)的儀表板,為它們添加一些功能,這些功能不是實現(xiàn)被動的數(shù)據(jù)收集,而是主動檢查收集到的數(shù)據(jù),從而允許我們構(gòu)建包含多個步驟的分析流。
【Python版本說明】
在撰寫本書時,Python的版本是Python 3.8,所以本書中的示例是用Python 3.8和Python 3.9的首批開發(fā)版本測試的。不建議使用更老的版本。本書中有極少數(shù)代碼示例不能在Python 3.7或Python 3.6中正常運行。
要學習本書內(nèi)容,你需要安裝Python pip。在安裝了Python后,系統(tǒng)中就應該已經(jīng)安裝了pip。有些操作系統(tǒng)故意在Python的默認安裝中去掉了pip,此時,你需要使用操作系統(tǒng)的包管理器自己安裝。這在基于Debian的系統(tǒng)中很常見,此時使用sudo apt install python3-pip就可以安裝pip。在其他操作系統(tǒng)中,可以使用python -m ensurepip --upgrade來讓Python找到pip的版本,或找到特定于你的操作系統(tǒng)的指令。
本書網(wǎng)站(https://github.com/MatthewWilkes/advanced-python-development)提供了代碼示例(也可訪問華章圖書官網(wǎng)http://www.hzbook.com,通過注冊并登錄個人賬號下載)和勘誤表的電子版。如果在學習本書的過程中遇到任何問題,應該首先訪問這些代碼示例和勘誤表。
馬修-威爾克斯
(Matthew Wilkes)
一名經(jīng)驗豐富的開發(fā)人員,他使用Python開發(fā)Web項目已經(jīng)有15年了。除了開發(fā)軟件外,他還長期為Python開發(fā)人員提供指導,積極推動開源軟件的發(fā)展,并為許多流行的框架提交過代碼。他對開源軟件的貢獻主要集中在數(shù)據(jù)庫的細節(jié)以及Web框架的安全交互方面。
●第1章 原型設計和環(huán)境1
1.1 Python中的原型設計1
1.1.1 使用REPL設計原型2
1.1.2 使用Python腳本設計原型5
1.1.3 使用腳本和pdb設計原型6
1.1.4 使用Jupyter設計原型9
1.1.5 本章的原型設計11
1.2 環(huán)境設置13
1.3 創(chuàng)建新項目14
1.3.1 設計腳本原型15
1.3.2 安裝依賴項18
1.4 導出到.py文件20
1.5 構(gòu)建命令行接口22
1.5.1 sys模塊和argv23
1.5.2 argparse24
1.5.3 click26
1.6 打破界限28
1.6.1 遠程內(nèi)核28
1.6.2 開發(fā)不能在本地運行的代碼32
1.7 完成后的腳本34
1.8 小結(jié)36
更多資源36
●第2章 測試、檢查和linting37
2.1 測試40
2.1.1 何時編寫測試42
2.1.2 創(chuàng)建格式化函數(shù)來提高可測試性43
2.1.3 pytest46
2.2 類型檢查56
2.2.1 安裝mypy57
2.2.2 添加類型提示58
2.2.3 子類和繼承60
2.2.4 泛型類型62
2.2.5 調(diào)試以及過度使用類型64
2.2.6 何時使用類型,何時避免使用類型66
2.2.7 將類型提示與代碼分離67
2.3 linting68
2.3.1 安裝flake8和black69
2.3.2 修復現(xiàn)有代碼70
2.3.3 自動運行71
2.3.4 拉取時運行73
2.4 小結(jié)74
更多資源75
●第3章 打包腳本76
3.1 術(shù)語77
3.2 目錄結(jié)構(gòu)77
3.3 安裝腳本和元數(shù)據(jù)80
3.4 依賴項80
3.5 聲明式配置82
3.5.1 在setup.py中需要避免的事項82
3.5.2 使用setup.cfg86
3.6 自定義索引服務器88
3.6.1 創(chuàng)建pypiserver90
3.6.2 持久性91
3.6.3 保密性92
3.6.4 完整性92
3.6.5 wheel格式和在安裝時執(zhí)行代碼93
3.7 使用入口點安裝控制臺腳本95
3.8 README、DEVELOP和CHANGES97
3.8.1 Markdown格式97
3.8.2 reStructuredText格式99
3.8.3 README101
3.8.4 CHANGES.md和版本化101
3.9 上游依賴項版本鎖定103
3.9.1 寬松鎖定103
3.9.2 嚴格鎖定104
3.9.3 應該使用哪種鎖定方案105
3.10 上傳版本105
3.11 小結(jié)107
更多資源107
●第4章 從腳本到框架109
4.1 編寫傳感器插件110
4.2 添加新的命令行選項113
4.2.1 子命令113
4.2.2 命令選項116
4.2.3 錯誤處理117
4.2.4 通過實參類型將解析工作
交給click120
4.2.5 自定義click實參類型121
4.2.6 常用選項123
4.3 允許使用第三方傳感器插件124
4.3.1 使用固定名稱檢測插件126
4.3.2 使用入口點檢測插件127
4.3.3 配置文件129
4.3.4 環(huán)境變量132
4.3.5 apd.sensors與類似程序的方法對比133
4.4 小結(jié)133
更多資源134
●第5章 其他接口136
5.1 Web微服務136
5.1.1 WSGI137
5.1.2 API設計142
5.1.3 Flask144
5.1.4 Python裝飾器146
5.1.5 測試視圖函數(shù)157
5.1.6 部署159
5.2 將軟件作為第三方軟件擴展160
5.2.1 與其他開發(fā)人員就簽名達成一致165
5.2.2 抽象基類167
5.2.3 后備策略170
5.2.4 綜合運用174
5.3 修復代碼中的序列化問題176
5.4 版本化API180
5.5 小結(jié)183
更多資源183
●第6章 聚合過程185
6.1 cookiecutter185
6.2 創(chuàng)建聚合包189
6.2.1 數(shù)據(jù)庫類型190
6.2.2 示例192
6.2.3 對象關(guān)系映射器193
6.2.4 版本化數(shù)據(jù)庫197
6.2.5 加載數(shù)據(jù)202
6.3 新技術(shù)209
6.3.1 數(shù)據(jù)庫210
6.3.2 自定義特性行為210
6.3.3 生成器210
6.4 小結(jié)210
更多資源211
●第7章 并行和異步212
7.1 非阻塞IO213
7.2 多線程與多進程218
7.2.1 低級線程219
7.2.2 字節(jié)碼222
7.2.3 鎖與死鎖225
7.2.4 避免全局狀態(tài)229
7.2.5 其他同步原語234
7.2.6 ProcessPoolExecutor241
7.2.7 使代碼使用多線程241
7.3 asyncio242
7.3.1 async def242
7.3.2 await243
7.3.3 async for245
7.3.4 async with249
7.3.5 異步鎖定原語249
7.3.6 使用同步庫251
7.3.7 使代碼異步化252
7.4 比較255
7.5 做出選擇255
7.6 小結(jié)257
更多資源258
●第8章 高級asyncio259
8.1 測試異步代碼259
8.1.1 測試代碼260
8.1.2 模擬對象以方便進行單元測試267
8.2 異步數(shù)據(jù)庫276
8.2.1 經(jīng)典SQLAlchemy風格277
8.2.2 使用run_in_executor280
8.2.3 查詢數(shù)據(jù)282
8.2.4 避免復雜查詢284
8.2.5 其他方案293
8.3 異步代碼中的全局變量294
8.4 小結(jié)296
更多資源297
●第9章 查看數(shù)據(jù)298
9.1 查詢函數(shù)298
9.1.1 過濾數(shù)據(jù)303
9.1.2 多層迭代器306
9.1.3 其他過濾器312
9.1.4 測試查詢函數(shù)313
9.2 顯示多個傳感器316
9.3 處理數(shù)據(jù)319
9.4 與Jupyter小部件進行交互323
9.4.1 增加嵌套的同步和異步代碼324
9.4.2 進行整理329
9.5 持久端點330
9.6 繪制地圖和地理數(shù)據(jù)330
9.6.1 新的圖類型333
9.6.2 在apd.aggregation中支持地圖類型的圖335
9.6.3 使用新配置繪制自定義地圖337
9.7 小結(jié)339
更多資源340
●第10章 加快速度341
10.1 優(yōu)化函數(shù)341
10.1.1 性能分析和線程343
10.1.2 解讀profile報表345
10.1.3 其他性能分析器348
10.2 優(yōu)化控制流352
10.2.1 可視化性能分析數(shù)據(jù)356
10.2.2 緩存360
10.3 小結(jié)369
更多資源369
●第11章 容錯371
11.1 錯誤處理371
11.1.1 從容器獲取項372
11.1.2 自定義異常377
11.1.3 涉及多個異常的堆棧跟蹤380
11.1.4 測試異常處理383
11.2 警告388
11.3 日志393
11.3.1 嵌套記錄器394
11.3.2 自定義動作396
11.3.3 記錄配置400
11.3.4 其他處理程序402
11.4 設計時規(guī)避問題402
11.5 小結(jié)407
更多資源408
●第12章 回調(diào)與數(shù)據(jù)分析409
12.1 生成器的數(shù)據(jù)流409
12.1.1 使用自己的輸出的生成器411
12.1.2 增強的生成器414
12.1.3 隊列420
12.1.4 選擇控制流422
12.2 動作的結(jié)構(gòu)423
12.2.1 分析協(xié)程424
12.2.2 攝入數(shù)據(jù)429
12.2.3 運行分析進程432
12.3 進程狀態(tài)434
12.4 擴展可用的動作439
12.5 小結(jié)441
更多資源442
后記443