本书分为三大部分,共计17章。第一部分(第1~2章)介绍了基础知识,包括如何配置开发环境和在网上寻求帮助。第二部分(第3~14章)介绍了Python编程的最佳实践、实用工具和技巧,不仅涵盖了如何编写高质量的Python代码、什么是高级的Python语法、如何使用专业开发者所用的命令行工具,还介绍了性能测量和大O算法分析,并用游戏实例演示了什么是最佳实践。第三部分(第15~17章)介绍了面向对象的Python,内容包括如何编写类、什么是类的继承,以及Python独有的面向对象功能。
* 《Python编程快速上手》的作者阿尔·斯维加特又一力作
* 《python编程从入门到实践》读者的进阶Python推荐读物
* 逐步可视化代码执行过程,助你编写规范、整洁的Python代码
* 通过益智游戏了解代码底层逻辑,像职业程序员一样使用Python
在学习Python的旅程中,你是否正在“绝望的沙漠”里徘徊?你已经学完了基础教程,却徘徊于不同的学习材料之间,感觉自己毫无长进。本书是“沙漠里的那片绿洲”。
作为《Python编程快速上手》的姊妹篇,本书专为想达到职业程序员水平却问路无门的人而写。作者拥有丰富的Python教学经验,所写内容既翔实细致,又深入浅出。你将通过三个方面实现从“快速上手”到“轻松进阶”的跃迁:解决初级进阶会遇到的重重困难;掌握Python编程的实践、工具和技巧;理解面向对象的Python。
【作者简介】
阿尔·斯维加特(Al Sweigart)是Python软件基金会Fellow,在Python社区颇具影响力,曾受邀在世界各地的Python大会上做主题演讲。他的Python入门书《Python编程快速上手》在全球范围内销售超过70万册。除了写作Python书,阿尔还在线授课。他的Python在线课程已覆盖100万+学生。
【译者简介】
张望
毕业于重庆大学,曾就职于腾讯看点、微信支付等部门,现就职于腾讯音乐集团商业广告部,负责广告投放等商业化系统的建设。腾讯开源项目WeTERM PMC成员,开源项目PyWebIO贡献者。
第 一部分 起步
第 1章 处理错误和寻求帮助 2
1.1 如何理解Python错误信息 2
1.1.1 检查回溯信息 2
1.1.2 搜索错误信息 5
1.2 借助linter 避免错误 7
1.3 如何寻求编程帮助 8
1.3.1 预先提供信息以避免反复补充 9
1.3.2 以实际问题的形式陈述问题 9
1.3.3 在合适的网站上提出你的问题 9
1.3.4 在标题中概述你的问题 9
1.3.5 说明代码的预期目的 9
1.3.6 包含完整的错误信息 9
1.3.7 分享全部代码 10
1.3.8 通过适当的格式化增强代码可读性 11
1.3.9 告诉帮忙者已经尝试过的方法 11
1.3.10 描述你的设置信息 12
1.4 样例:如何寻求帮助 12
1.5 小结 13
第 2章 环境设置和命令行 14
2.1 文件系统 14
2.1.1 Python中的路径 15
2.1.2 主目录 16
2.1.3 当前工作目录 16
2.1.4 绝对路径和相对路径 17
2.2 程序和进程 18
2.3 命令行 18
2.3.1 打开终端窗口 19
2.3.2 使用命令行运行程序 20
2.3.3 使用命令行参数 21
2.3.4 在命令行中使用-c 运行Python代码 22
2.3.5 从命令行运行Python 程序 23
2.3.6 运行py.exe 程序 23
2.3.7 在Python 程序中运行命令 23
2.3.8 使用Tab 补全命令减少输入量 24
2.3.9 查看历史命令 24
2.3.10 使用常用命令 25
2.4 环境变量和PATH 32
2.4.1 查看环境变量 32
2.4.2 使用PATH 环境变量 33
2.4.3 更改命令行的PATH 环境变量 34
2.4.4 在Windows 上将文件夹永久添加到PATH 34
2.4.5 在macOS 和Linux 上将文件夹永久添加到PATH 35
2.5 不借助命令行运行Python 程序 36
2.5.1 在Windows 上运行Python程序 36
2.5.2 在macOS 上运行Python 程序 37
2.5.3 在Ubuntu Linux 上运行Python程序 37
2.6 小结 38
第二部分 最佳实践、工具和技巧
第3章 使用Black 进行代码格式化 40
3.1 让程序员招人烦的错误做法 40
3.2 风格指南和PEP 8 41
3.3 水平间距 41
3.3.1 使用空格进行缩进 41
3.3.2 行内间距 42
3.4 垂直间距 45
3.4.1 垂直间距示例 46
3.4.2 垂直间距的最佳实践 46
3.5 Black:毫不妥协的代码格式化工具 48
3.5.1 安装Black 48
3.5.2 在命令行中运行Black 48
3.5.3 对部分代码禁用Black 51
3.6 小结 52
第4章 选择易懂的名称 53
4.1 命名风格 54
4.2 PEP 8 的命名风格 54
4.3 适当的名称长度 54
4.3.1 太短的名称 55
4.3.2 太长的名称 56
4.4 起易于搜索的名称 57
4.5 避免笑话、双关语和需要文化背景才能理解的词汇 57
4.6 不要覆盖内置名称 58
4.7 史上最差的变量名 59
4.8 小结 59
第5章 揪出代码的坏味道 61
5.1 重复的代码 61
5.2 魔数 63
5.3 注释掉的代码和死代码 65
5.4 打印调试 67
5.5 带有数字后缀的变量 67
5.6 本该是函数或者模块的类 68
5.7 嵌套列表解析式 69
5.8 空的except块和糟糕的错误信息 70
5.9 代码坏味道的谬误 71
5.9.1 谬误:函数应该仅在末尾处有一个return语句 72
5.9.2 谬误:函数最多只能有一个try语句 72
5.9.3 谬误:使用flag参数不好 73
5.9.4 谬误:全局变量不好 73
5.9.5 谬误:注释是不必要的 74
5.10 小结 75
第6章 编写Python 风格的代码 76
6.1 Python 之禅 76
6.2 学着喜欢强制缩进 79
6.3 使用timeit模块衡量性能 80
6.4 常被误用的语法 82
6.4.1 使用enumerate()而不是range() 82
6.4.2 使用with 语句代替open()和close() 83
6.4.3 用is 跟None 做比较而不用== 84
6.5 格式化字符串 84
6.5.1 如果字符串有很多反斜杠,请使用原始字符串 84
6.5.2 使用f-string 格式化字符串 85
6.6 制作列表的浅副本 86
6.7 以Python 风格使用字典 87
6.7.1 在字典中使用get()和setdefault() 87
6.7.2 使用collections.defaultdict()设置默认值 89
6.7.3 使用字典代替switch 语句 89
6.8 条件表达式:Python“丑陋”的三元运算符 90
6.9 处理变量的值 92
6.9.1 链式赋值和比较运算符 92
6.9.2 验证变量是否为多个值中的一个 93
6.10 小结 93
第7章 编程术语 95
7.1 定义 95
7.1.1 作为语言的Python 和作为解释器的Python 96
7.1.2 垃圾回收 96
7.1.3 字面量 97
7.1.4 关键字 98
7.1.5 对象、值、实例和身份 98
7.1.6 项 101
7.1.7 可变和不可变 101
7.1.8 索引、键和哈希值 104
7.1.9 容器、序列、映射和集合类型 106
7.1.10 特殊方法 107
7.1.11 模块和包 108
7.1.12 可调用对象和头等对象 108
7.2 经常被混淆的术语 109
7.2.1 语句和表达式 109
7.2.2 块、子句和主体 110
7.2.3 变量和特性 111
7.2.4 函数和方法 111
7.2.5 可迭代对象和迭代器 112
7.2.6 语法错误、运行时错误和语义错误 113
7.2.7 形参和实参 115
7.2.8 显式类型转换和隐式类型转换 115
7.2.9 属性和特性 115
7.2.10 字节码和机器码 116
7.2.11 脚本和程序,以及脚本语言和编程语言 116
7.2.12 库、框架、SDK、引擎、API 117
7.3 小结 117
第8章 常见的Python陷阱 119
8.1 循环列表的同时不要增删其中的元素 119
8.2 复制可变值时务必使用copy.copy()和copy.deepcopy() 125
8.3 不要用可变值作为默认参数 128
8.4 不要通过字符串连接创建字符串 130
8.5 不要指望sort()按照字母顺序排序 131
8.6 不要假设浮点数是完全准确的 132
8.7 不要使用链式!=运算符 135
8.8 不要忘记在仅有一项的元组中添加逗号 135
8.9 小结 136
第9章 Python的奇特难懂之处 137
9.1 为什么256 是256,而257 不是257 137
9.2 字符串驻留 138
9.3 假的Python 增量运算符和减量运算符 139
9.4 传递空列表给all() 141
9.5 布尔值是整数值 141
9.6 链式使用多种运算符 143
9.7 Python 的反重力特性 143
9.8 小结 144
第 10章 编写高效的函数 145
10.1 函数名 145
10.2 函数大小的权衡 146
10.3 函数的形参和实参 148
10.3.1 默认参数 149
10.3.2 使用*和**向函数传参 149
10.3.3 使用*创建可变参数函数 150
10.3.4 使用**创建可变参数函数 153
10.3.5 使用*和**创建包装函数 154
10.4 函数式编程 155
10.4.1 副作用 155
10.4.2 高阶函数 157
10.4.3 lambda 函数 157
10.4.4 在列表推导式中进行映射和过滤 158
10.5 返回值的数据类型应该不变 159
10.6 抛出异常和返回错误码 161
10.7 小结 162
第 11章 注释、文档字符串和类型提示 163
11.1 注释 164
11.1.1 注释风格 164
11.1.2 内联注释 165
11.1.3 说明性的注释 166
11.1.4 总结性的注释 166
11.1.5 “经验之谈”的注释 167
11.1.6 法律注释 167
11.1.7 注释的专业性 167
11.1.8 代码标签和TODO 注释 168
11.1.9 神奇的注释和源文件编码 168
11.2 文档字符串 169
11.3 类型提示 171
11.3.1 使用静态分析器 172
11.3.2 为多种类型设置类型提示 174
11.3.3 为列表、字典等设置类型提示 176
11.3.4 通过注释向后移植类型提示 176
11.4 小结 177
第 12章 通过Git管理项目 . 179
12.1 Git 提交和仓库 179
12.2 使用Cookiecutter新建Python项目 180
12.3 安装Git 182
12.3.1 配置Git 用户名和电子邮件 182
12.3.2 安装GUI Git 工具 182
12.4 Git 的工作流程 183
12.4.1 Git 是如何追踪文件状态的 184
12.4.2 为什么要暂存文件 185
12.5 在计算机上创建Git 仓库 185
12.5.1 添加供Git 追踪的文件 187
12.5.2 忽略仓库中的文件 188
12.5.3 提交修改 189
12.5.4 从仓库中删除文件 193
12.5.5 重命名和移动仓库中的文件 194
12.6 查看提交日志 195
12.7 恢复历史修改 196
12.7.1 撤销未提交的本地修改 196
12.7.2 取消暂存的文件 197
12.7.3 回滚近期的提交 197
12.7.4 回滚到单个文件的某次提交 198
12.7.5 重写提交历史 199
12.8 GitHub 和git推送命令 199
12.8.1 将一个已存在的仓库推送到GitHub 200
12.8.2 克隆已存在的GitHub仓库 201
12.9 小结 202
第 13章 性能测量和大O算法分析 203
13.1 timeit模块 203
13.2 cProfile分析器 206
13.3 大O算法分析 208
13.4 大O阶 208
13.4.1 使用书架打比方描述大O阶 209
13.4.2 大O 测量的是最坏情况 212
13.5 确定代码的大O 阶 214
13.5.1 为什么低阶项和系数不重要 215
13.5.2 大O 分析实例 216
13.5.3 常见函数调用的大O 阶 219
13.5.4 一眼看出大O 阶 220
13.5.5 当n 很小时,大O并不重要,而n通常都很小 221
13.6 小结 . 221
第 14章 项目实战 222
14.1 汉诺塔 . 222
14.1.1 输出 223
14.1.2 源代码 224
14.1.3 编写代码 227
14.2 四子棋 233
14.2.1 输出 233
14.2.2 源代码 234
14.2.3 编写代码 238
14.3 小结 245
第三部分 面向对象的Python
第 15章 面向对象编程和类 248
15.1 拿现实世界打比方:填写表格 248
15.2 基于类创建对象 250
15.3 创建一个简单的类——WizCoin 251
15.3.1 方法__init__()和self 253
15.3.2 特性 254
15.3.3 私有特性和私有方法 255
15.4 函数type()和特性__qualname__ 257
15.5 非OOP 和OOP 的例子:井字棋 258
15.6 为现实世界设计类是一件难事儿 263
15.7 小结 263
第 16章 面向对象编程和继承 265
16.1 继承的原理 265
16.1.1 重写方法 267
16.1.2 super()函数 269
16.1.3 倾向于组合而非继承 271
16.1.4 继承的缺点 272
16.2 函数isinstance()和issubclass() 274
16.3 类方法 275
16.4 类特性 277
16.5 静态方法 278
16.6 何时应该使用类和静态的面向对象特性 278
16.7 面向对象的行话 279
16.7.1 封装 279
16.7.2 多态性 279
16.8 何时不应该使用继承 279
16.9 多重继承 280
16.10 方法解析顺序 282
16.11 小结 283
第 17章 Python 风格的面向对象编程:属性和魔术方法 285
17.1 属性 285
17.1.1 将特性转换为属性 286
17.1.2 使用setter 验证数据 288
17.1.3 只读属性 290
17.1.4 什么时候应该使用属性 291
17.2 Python 的魔术方法 291
17.2.1 字符串表示魔术方法 292
17.2.2 数值魔术方法 294
17.2.3 反射数值魔术方法 297
17.2.4 原地魔术方法 299
17.2.5 比较魔术方法 301
17.3 小结 305