前言 v
第 1章 變量與注釋 1
1.1 基礎知識 2
1.1.1 變量常見用法 2
1.1.2 給變量注明類型 4
1.1.3 變量命名原則 6
1.1.4 注釋基礎知識 11
1.2 案例故事 14
奇怪的冒泡排序算法 15
1.3 編程建議 17
1.3.1 保持變量的一緻性 18
1.3.2 變量定義盡量靠近使用 18
1.3.3 定義臨時變量提升可讀性 20
1.3.4 同一作用域內不要有太多變量 21
1.3.5 能不定義變量就彆定義 22
1.3.6 不要使用locals() 23
1.3.7 空行也是一種“注釋” 24
1.3.8 先寫注釋,後寫代碼 25
1.4 總結 26
第 2章 數值與字符串 28
2.1 基礎知識 29
2.1.1 數值基礎 29
2.1.2 布爾值其實也是數字 31
2.1.3 字符串常用操作 31
2.1.4 不常用但特彆好用的字符串方法 34
2.1.5 字符串與字節串 36
2.2 案例故事 39
2.2.1 代碼裏的“密碼” 39
2.2.2 彆輕易成為SQL語句“大師” 41
2.3 編程建議 44
2.3.1 不必預計算字麵量錶達式 44
2.3.2 使用特殊數字:“無窮大” 46
2.3.3 改善超長字符串的可讀性 47
2.3.4 彆忘瞭以r開頭的字符串內置方法 48
2.3.5 不要害怕字符串拼接 49
2.4 總結 50
第3章 容器類型 53
3.1 基礎知識 54
3.1.1 列錶常用操作 54
3.1.2 理解列錶的可變性 56
3.1.3 常用元組操作 60
3.1.4 具名元組 61
3.1.5 字典常用操作 63
3.1.6 認識字典的有序性與無序性 66
3.1.7 集閤常用操作 68
3.1.8 瞭解對象的可哈希性 71
3.1.9 深拷貝與淺拷貝 72
3.2 案例故事 74
分析網站訪問日誌 75
3.3 編程建議 83
3.3.1 用按需返迴替代容器 83
3.3.2 瞭解容器的底層實現 86
3.3.3 掌握如何快速閤並字典 89
3.3.4 使用有序字典去重 91
3.3.5 彆在遍曆列錶時同步修改 92
3.3.6 編寫推導式的兩個“不要” 92
3.3.7 讓函數返迴NamedTuple 94
3.4 總結 95
第4章 條件分支控製流 97
4.1 基礎知識 98
4.1.1 分支慣用寫法 98
4.1.2 修改對象的布爾值 101
4.1.3 與None比較時使用is運算符 103
4.2 案例故事 105
消失的分支 105
4.3 編程建議 112
4.3.1 盡量避免多層分支嵌套 112
4.3.2 彆寫太復雜的條件錶達式 114
4.3.3 盡量降低分支內代碼的相似性 115
4.3.4 使用“德摩根定律” 116
4.3.5 使用all()/any()函數構建條件錶達式 117
4.3.6 留意and和or的運算優先級 118
4.3.7 避開or運算符的陷阱 118
4.4 總結 119
第5章 異常與錯誤處理 121
5.1 基礎知識 122
5.1.1 優先使用異常捕獲 122
5.1.2 try語句常用知識 124
5.1.3 拋齣異常,而不是返迴錯誤 127
5.1.4 使用上下文管理器 129
5.2 案例故事 133
5.2.1 提前崩潰也挺好 133
5.2.2 異常與抽象一緻性 136
5.3 編程建議 139
5.3.1 不要隨意忽略異常 139
5.3.2 不要手動做數據校驗 140
5.3.3 拋齣可區分的異常 142
5.3.4 不要使用assert來檢查參數閤法性 144
5.3.5 無須處理是最好的錯誤處理 145
5.4 總結 149
第6章 循環與可迭代對象 151
6.1 基礎知識 152
6.1.1 迭代器與可迭代對象 152
6.1.2 修飾可迭代對象優化循環 158
6.1.3 使用itertools模塊優化循環 160
6.1.4 循環語句的else關鍵字 162
6.2 案例故事 164
數字統計任務 164
6.3 編程建議 168
6.3.1 中斷嵌套循環的正確方式 168
6.3.2 巧用next()函數 170
6.3.3 當心已被耗盡的迭代器 171
6.4 總結 172
第7章 函數 174
7.1 基礎知識 175
7.1.1 函數參數的常用技巧 175
7.1.2 函數返迴的常見模式 179
7.1.3 常用函數模塊:functools 184
7.2 案例故事 187
函數與狀態 187
7.3 編程建議 194
7.3.1 彆寫太復雜的函數 194
7.3.2 一個函數隻包含一層抽象 196
7.3.3 優先使用列錶推導式 203
7.3.4 你沒有那麼需要lambda 204
7.3.5 瞭解遞歸的局限性 205
7.4 總結 207
第8章 裝飾器 209
8.1 基礎知識 211
8.1.1 裝飾器基礎 211
8.1.2 使用functools.wraps()修飾包裝函數 213
8.1.3 實現可選參數裝飾器 215
8.1.4 用類來實現裝飾器(函數替換) 217
8.1.5 用類來實現裝飾器(實例替換) 219
8.1.6 使用wrapt模塊助力裝飾器編寫 221
8.2 編程建議 223
8.2.1 瞭解裝飾器的本質優勢 223
8.2.2 使用類裝飾器替代元類 225
8.2.3 彆弄混裝飾器和裝飾器模式 226
8.2.4 淺裝飾器,深實現 227
8.3 總結 228
第9章 麵嚮對象編程 230
9.1 基礎知識 232
9.1.1 類常用知識 232
9.1.2 內置類方法裝飾器 235
9.1.3 鴨子類型及其局限性 239
9.1.4 抽象類 242
9.1.5 多重繼承與MRO 248
9.1.6 其他知識 251
9.2 案例故事 255
繼承是把雙刃劍 255
9.3 編程建議 265
9.3.1 使用__init_subclass__替代元類 265
9.3.2 在分支中尋找多態的應用時機 266
9.3.3 有序組織你的類方法 268
9.3.4 函數搭配,乾活不纍 270
9.4 總結 274
第 10章 麵嚮對象設計原則(上) 276
10.1 類型注解基礎 278
10.2 SRP:單一職責原則 279
10.2.1 案例:一個簡單的Hacker News爬蟲 280
10.2.2 違反SRP的壞處 283
10.2.3 大類拆小類 284
10.3 OCP:開放-關閉原則 285
10.3.1 接受OCP的考驗 286
10.3.2 通過繼承改造代碼 288
10.3.3 使用組閤與依賴注入 289
10.3.4 使用數據驅動 292
10.4 總結 294
第 11章 麵嚮對象設計原則(下) 295
11.1 LSP:裏式替換原則 296
11.1.1 子類隨意拋齣異常 296
11.1.2 子類隨意調整方法參數與返迴值 300
11.1.3 基於隱式閤約違反LSP 304
11.1.4 LSP小結 306
11.2 DIP:依賴倒置原則 306
11.2.1 案例:按來源統計Hacker News條目數量 307
11.2.2 為腳本編寫單元測試 309
11.2.3 實現DIP 311
11.2.4 倒置後的單元測試 314
11.2.5 DIP小結 315
11.3 ISP:接口隔離原則 317
11.3.1 案例:處理頁麵歸檔需求 317
11.3.2 修改實體類 318
11.3.3 違反ISP 320
11.3.4 分拆接口 320
11.3.5 其他違反ISP的場景 322
11.4 總結 322
第 12章 數據模型與描述符 324
12.1 基礎知識 326
12.1.1 字符串魔法方法 326
12.1.2 比較運算符重載 329
12.1.3 描述符 332
12.2 案例故事 341
處理旅遊數據的三種方案 341
12.3 編程建議 350
12.3.1 認識__hash__的危險性 350
12.3.2 數據模型不是“躺贏”之道 351
12.3.3 不要依賴__del__方法 353
12.4 總結 354
第 13章 開發大型項目 356
13.1 常用工具介紹 357
13.1.1 flake8 357
13.1.2 isort 360
13.1.3 black 361
13.1.4 pre-commit 364
13.1.5 mypy 365
13.2 單元測試簡介 366
13.2.1 unittest 367
13.2.2 pytest 369
13.3 有關單元測試的建議 375
13.3.1 寫單元測試不是浪費時間 375
13.3.2 不要總想著“補”測試 377
13.3.3 難測試的代碼就是爛代碼 378
13.3.4 像應用代碼一樣對待測試代碼 379
13.3.5 避免教條主義 380
13.4 總結 381
結語 383
· · · · · · (
收起)