第Ⅰ部分 函数 3
第1章 装饰器 3
1.1 理解装饰器 3
1.2 装饰器语法 4
1.3 在何处使用装饰器 6
1.4 编写装饰器的理由 6
1.5 编写装饰器的时机 7
1.5.1 附加功能 7
1.5.2 数据的清理或添加 7
1.5.3 函数注册 7
1.6 编写装饰器 7
1.6.1 初始示例:函数注册表 8
1.6.2 执行时封装代码 9
1.6.3 装饰器参数 16
1.7 装饰类 20
1.8 类型转换 23
1.9 小结 25
第2章 上下文管理器 27
2.1 上下文管理器的定义 27
2.2 上下文管理器的语法 28
2.2.1 with语句 28
2.2.2 enter和exit方法 28
2.2.3 异常处理 29
2.3 何时应该编写上下文管理器 30
2.3.1 资源清理 30
2.3.2 避免重复 31
2.4 更简单的语法 38
2.5 小结 39
第3章 生成器 41
3.1 理解生成器 41
3.2 理解生成器语法 41
3.2.1 next函数 43
3.2.2 StopIteration异常 45
3.3 生成器之间的交互 47
3.4 迭代对象与迭代器 49
3.5 标准库中的生成器 50
3.5.1 range 50
3.5.2 dict.items及其家族 50
3.5.3 zip 51
3.5.4 map 52
3.5.5 文件对象 52
3.6 何时编写生成器 53
3.6.1 分块访问数据 53
3.6.2 分块计算数据 54
3.7 何时使用生成器单例模式 54
3.8 生成器内部的生成器 55
3.9 小结 56
第Ⅱ部分 类 59
第4章 魔术方法 59
4.1 魔术方法语法 59
4.2 可用的魔术方法 60
4.2.1 创建与销毁 61
4.2.2 类型转换 63
4.2.3 比较 65
4.3 其他魔术方法 75
4.4 小结 76
第5章 元类 77
5.1 类与对象 77
5.1.1 直接使用type 78
5.1.2 type链 80
5.1.3 type的角色 80
5.2 编写元类 81
5.2.1 _new_方法 81
5.2.2 _ new_与_init_方法 81
5.2.3 元类示例 82
5.2.4 元类继承 82
5.3 使用元类 84
5.3.1 Python 3 85
5.3.2 Python 2 85
5.3.3 需要跨版本执行的代码怎么办 85
5.3.4 跨版本兼容性在何时重要 86
5.4 何时使用元类 87
5.4.1 说明性类声明 87
5.4.2 类验证 88
5.4.3 非继承属性 90
5.5 显式选择的问题 91
5.6 meta-coding 92
5.7 小结 94
第6章 类工厂 95
6.1 类型回顾 95
6.2 理解类工厂函数 96
6.3 决定何时应该编写类工厂 98
6.3.1 运行时属性 98
6.3.2 避免类属性一致性问题 102
6.3.3 关于单例模式问题的解答 105
6.4 小结 107
第7章 抽象基类 109
7.1 使用抽象基类 109
7.2 声明虚拟子类 110
7.2.1 声明虚拟子类的原因 111
7.2.2 使用register作为装饰器 113
7.2.3 _subclasshook_ 113
7.3 声明协议 115
7.3.1 其他现有的方法 115
7.3.2 抽象基类的价值 118
7.3.3 抽象属性 120
7.3.4 抽象类或静态方法 121
7.4 内置抽象基类 122
7.4.1 只包含一个方法的抽象基类 122
7.4.2 可供集合使用的抽象基类 123
7.4.3 额外的抽象基类 124
7.5 小结 124
第Ⅲ部分 数据 127
第8章 字符串与Unicode 127
8.1 文本字符串与字节字符串 127
8.2 包含非ASCII字符的字符串 132
8.2.1 观察区别 132
8.2.2 Unicode是ASCII的超集 133
8.3 其他编码 133
8.4 读取文件 135
8.4.1 Python 3 135
8.4.2 Python 2 137
8.4.3 读取其他源 137
8.4.4 指定Python文件编码 137
8.5 严格编码 139
8.5.1 不触发错误 139
8.5.2 注册错误处理程序 140
8.6 小结 141
第9章 正则表达式 143
9.1 使用正则表达式的原因 143
9.2 Python中的正则表达式 144
9.2.1 原始字符串 144
9.2.2 match对象 145
9.2.3 找到多个匹配 145
9.3 基本正则表达式 146
9.3.1 字符组 146
9.3.2 可选字符 150
9.3.3 重复 151
9.4 分组 152
9.4.1 零分组 154
9.4.2 命名分组 155
9.4.3 引用已经存在的分组 156
9.5 先行断言 157
9.6 标记 158
9.6.1 不区分大小写 158
9.6.2 ASCII与Unicode 159
9.6.3 点匹配换行符 159
9.6.4 多行模式 159
9.6.5 详细模式 160
9.6.6 调试模式 160
9.6.7 使用多个标记 160
9.6.8 内联标记 160
9.7 替换 161
9.8 已编译的正则表达式 162
9.9 小结 163
第Ⅳ部分 其他高级主题 167
第10章 Python 2与Python 3 167
10.1 跨版本兼容性策略 167
10.1.1 _future_模块 168
10.1.2 2to3 168
10.1.3 限制 170
10.1.4 six 170
10.2 Python 3中的变更 171
10.2.1 字符串与Unicode 171
10.2.2 Print函数 171
10.2.3 除法 172
10.2.4 绝对与相对导入 173
10.2.5 “老式风格”类的移除 174
10.2.6 元类语法 175
10.2.7 异常语法 176
10.2.8 字典方法 178
10.2.9 函数方法 179
10.2.10 迭代器 179
10.3 标准库重定位 180
10.3.1 合并“高效”模块 180
10.3.2 URL模块 181
10.3.3 重命名 181
10.3.4 其他包重组 181
10.4 版本检测 182
10.5 小结 182
第11章 单元测试 183
11.1 测试的连续性 183
11.1.1 副本生态系统 183
11.1.2 隔离的环境 184
11.1.3 优点与缺点 185
11.2 测试代码 185
11.2.1 代码布局 186
11.2.2 测试函数 186
11.2.3 assert语句 188
11.3 单元测试框架 188
11.3.1 执行单元测试 189
11.3.2 载入测试 192
11.4 模拟 193
11.4.1 模拟函数调用 193
11.4.2 断言被模拟的调用 195
11.4.3 检查模拟 197
11.4.4 检查调用 199
11.5 其他测试工具 199
11.6 小结 201
第12章 CLI工具 203
12.1 optparse 203
12.1.1 一个简单的参数 203
12.1.2 选项 205
12.1.3 使用optparse的原因 212
12.2 argparse 213
12.2.1 本质 213
12.2.2 参数与选项 214
12.2.3 使用argparse的理由 220
12.3 小结 221
第13章 asyncio模块 223
13.1 事件循环 223
13.2 协程 227
13.3 Future对象与Task对象 229
13.3.1 Future对象 229
13.3.2 Task对象 230
13.4 回调 231
13.4.1 不保证成功 232
13.4.2 幕后 232
13.4.3 带参数的回调 233
13.5 任务聚合 233
13.5.1 聚集任务 234
13.5.2 等待任务 235
13.6 队列 238
13.7 服务器 240
13.8 小结 242
第14章 代码风格 243
14.1 原则 243
14.1.1 假定你的代码需要维护 243
14.1.2 保持一致性 244
14.1.3 考虑对象在程序中的存在方式,尤其是那些带有数据的对象 244
14.1.4 不要做重复工作 244
14.1.5 让注释讲故事 245
14.1.6 奥卡姆剃刀原则 245
14.2 标准 245
14.2.1 简洁的规则 246
14.2.2 文档字符串 246
14.2.3 空行 246
14.2.4 导入 247
14.2.5 变量 247
14.2.6 注释 248
14.2.7 行长度 248
14.3 小结 249