新書推薦:
《
有法与无法:清代的州县制度及其运作 最新修订版
》
售價:NT$
640.0
《
重启春光
》
售價:NT$
214.0
《
“玉”见中国:玉器文化与中华文明(追寻玉出山河的前世今生,饱览中国万年玉文化的史诗画卷)
》
售價:NT$
690.0
《
官治与自治:20 世纪上半期的中国县制 最新修订版
》
售價:NT$
640.0
《
迈尔斯普通心理学
》
售價:NT$
760.0
《
面部填充术
》
售價:NT$
990.0
《
尼泊尔史:王权与变革
》
售價:NT$
430.0
《
战争事典085:德国人眼中的欧战胜利日:纳粹德国的最终失败
》
售價:NT$
499.0
|
編輯推薦: |
本书由奋战在Python开发一线近20年的Luciano Ramalho执笔,Victor Stinner、Alex Martelli等Python大咖担纲技术审稿人,从语言设计层面剖析编程细节,兼顾Python 3和Python 2,告诉你Python中不亲自动手实践就无法理解的语言陷阱成因和解决之道,教你写出风格地道的Python代码。
● Python数据模型:理解为什么特殊方法是对象行为一致的关键。
● 数据结构:充分利用内置类型,理解Unicode文本和字节二象性。
● 把函数视作对象:把Python函数视作一等对象,并了解这一点对流行的设计模式的影响。
● 面向对象习惯用法:通过构建类学习引用、可变性、接口、运算符重载和多重继承。
● 控制流程:学习使用上下文管理器、生成器、协程,以及通过concurrent.futures和asyncio包实现的并发。
● 元编程:理解特性、描述符、类装饰器和元类的工作原理。
|
內容簡介: |
《流畅的Python》一书致力于帮助Python开发人员挖掘这门语言及相关程序库的优秀特性,避免重复劳动,同时写出简洁、流畅、易读、易维护,并且具有地道Python风格的代码。本书尤其深入探讨了Python语言的高级用法,涵盖数据结构、Python风格的对象、并行与并发,以及元编程等不同的方面。
“很荣幸担任这本优秀图书的技术审校。这本书能帮助很多中级Python程序员掌握这门语言,我也从中学到了相当多的知识!”
——Alex Martelli,Python软件基金会成员
“对于想要扩充知识的中级和高级Python程序员来说,这本书是充满了实用编程技巧的宝藏。”
——Daniel和Audrey Roy Greenfeld,Two Scoops of Django作者
|
關於作者: |
Luciano Ramalho
从1998年起就成为了Python程序员。他是Python软件基金会的成员,Python.pro.br(巴西的一家培训公司)的共同所有者,还是巴西第一个众创空间Garoa Hacker Clube的联合创始人。他领导过多个软件开发团队,还在巴西的媒体、银行和政府部门教授Python课程。
译者简介:
安道
专注于现代计算机技术的自由翻译,译有《Flask Web 开发》《Python 网络编程攻略》《Ruby on Rails 教程》等书。
个人网站:http:about.ac。作者简介:
Luciano Ramalho
从1998年起就成为了Python程序员。他是Python软件基金会的成员,Python.pro.br(巴西的一家培训公司)的共同所有者,还是巴西第一个众创空间Garoa Hacker Clube的联合创始人。他领导过多个软件开发团队,还在巴西的媒体、银行和政府部门教授Python课程。
译者简介:
安道
专注于现代计算机技术的自由翻译,译有《Flask Web 开发》《Python 网络编程攻略》《Ruby on Rails 教程》等书。
个人网站:http:about.ac。
吴珂
现为Airbnb公司软件工程师,所在团队主要负责开发和维护各类可伸缩、高性能服务,并在Airbnb内推广面向服务的系统架构。在分布式系统、云存储服务和跨平台SDK开发,以及大规模数据处理等方面有多年经验。
|
目錄:
|
前言 xvii
第一部分 序幕
第1章 Python 数据模型 2
1.1 一摞 Python 风格的纸牌 3
1.2 如何使用特殊方法 6
1.2.1 模拟数值类型 7
1.2.2 字符串表示形式 9
1.2.3 算术运算符 10
1.2.4 自定义的布尔值 10
1.3 特殊方法一览 10
1.4 为什么 len 不是普通方法 12
1.5 本章小结 12
1.6 延伸阅读 13
第二部分 数据结构
第2章 序列构成的数组 16
2.1 内置序列类型概览 17
2.2 列表推导和生成器表达式 18
2.2.1 列表推导和可读性 18
2.2.2 列表推导同 filter 和 map 的比较 20
2.2.3 笛卡儿积 20
2.2.4 生成器表达式 21
2.3 元组不仅仅是不可变的列表 22
2.3.1 元组和记录 23
2.3.2 元组拆包 23
2.3.3 嵌套元组拆包 25
2.3.4 具名元组 26
2.3.5 作为不可变列表的元组 27
2.4 切片 28
2.4.1 为什么切片和区间会忽略最后一个元素 28
2.4.2 对对象进行切片 29
2.4.3 多维切片和省略 30
2.4.4 给切片赋值 31
2.5 对序列使用 + 和 * 31
2.6 序列的增量赋值 33
2.7 list.sort 方法和内置函数 sorted 36
2.8 用 bisect 来管理已排序的序列 37
2.8.1 用 bisect 来搜索 38
2.8.2 用 bisect.insort 插入新元素 40
2.9 当列表不是首选时 41
2.9.1 数组 41
2.9.2 内存视图 44
2.9.3 NumPy 和 SciPy 45
2.9.4 双向队列和其他形式的队列 47
2.10 本章小结 49
2.11 延伸阅读 50
第3章 字典和集合 54
3.1 泛映射类型 54
3.2 字典推导 56
3.3 常见的映射方法 57
3.4 映射的弹性键查询 61
3.4.1 defaultdict :处理找不到的键的一个选择 61
3.4.2 特殊方法 __missing__ 62
3.5 字典的变种 65
3.6 子类化 UserDict 65
3.7 不可变映射类型 67
3.8 集合论 68
3.8.1 集合字面量 69
3.8.2 集合推导 71
3.8.3 集合的操作 71
3.9 dict 和 set 的背后 73
3.9.1 一个关于效率的实验 74
3.9.2 字典中的散列表 75
3.9.3 dict 的实现及其导致的结果 78
3.9.4 set 的实现以及导致的结果 80
3.10 本章小结 80
3.11 延伸阅读 81
第4章 文本和字节序列 83
4.1 字符问题 84
4.2 字节概要 85
4.3 基本的编解码器 88
4.4 了解编解码问题 89
4.4.1 处理 UnicodeEncodeError 90
4.4.2 处理 UnicodeDecodeError 90
4.4.3 使用预期之外的编码加载模块时抛出的 SyntaxError 91
4.4.4 如何找出字节序列的编码 92
4.4.5 BOM:有用的鬼符 93
4.5 处理文本文件 94
4.6 为了正确比较而规范化 Unicode 字符串 99
4.6.1 大小写折叠 101
4.6.2 规范化文本匹配实用函数 102
4.6.3 极端“规范化”:去掉变音符号 103
4.7 Unicode 文本排序 105
4.8 Unicode 数据库 108
4.9 支持字符串和字节序列的双模式 API 109
4.9.1 正则表达式中的字符串和字节序列 109
4.9.2 os 函数中的字符串和字节序列 111
4.10 本章小结 112
4.11 延伸阅读 113
第三部分 把函数视作对象
第5章 一等函数 118
5.1 把函数视作对象 119
5.2 高阶函数 120
5.3 匿名函数 122
5.4 可调用对象 122
5.5 用户定义的可调用类型 123
5.6 函数内省 124
5.7 从定位参数到仅限关键字参数 126
5.8 获取关于参数的信息 127
5.9 函数注解 131
5.10 支持函数式编程的包 132
5.10.1 operator 模块 132
5.10.2 使用 functools.partial 冻结参数 135
5.11 本章小结 137
5.12 延伸阅读 137
第6章 使用一等函数实现设计模式 141
6.1 案例分析:重构“策略”模式 142
6.1.1 经典的“策略”模式 142
6.1.2 使用函数实现“策略”模式 145
6.1.3 选择最佳策略:简单的方式 148
6.1.4 找出模块中的全部策略 149
6.2 “命令”模式 150
6.3 本章小结 151
6.4 延伸阅读 152
第7章 函数装饰器和闭包 154
7.1 装饰器基础知识 155
7.2 Python 何时执行装饰器 156
7.3 使用装饰器改进“策略”模式 157
7.4 变量作用域规则 159
7.5 闭包 161
7.6 nonlocal 声明 164
7.7 实现一个简单的装饰器 165
7.8 标准库中的装饰器 168
7.8.1 使用 functools.lru_cache 做备忘 168
7.8.2 单分派泛函数 170
7.9 叠放装饰器 172
7.10 参数化装饰器 173
7.10.1 一个参数化的注册装饰器 173
7.10.2 参数化 clock 装饰器 175
7.11 本章小结 177
7.12 延伸阅读 178
第四部分 面向对象惯用法
第8章 对象引用、可变性和垃圾回收 182
8.1 变量不是盒子 183
8.2 标识、相等性和别名 184
8.2.1 在 == 和 is 之间选择 185
8.2.2 元组的相对不可变性 186
8.3 默认做浅复制 187
8.4 函数的参数作为引用时 190
8.4.1 不要使用可变类型作为参数的默认值 191
8.4.2 防御可变参数 193
8.5 del 和垃圾回收 195
8.6 弱引用 196
8.6.1 WeakValueDictionary 简介 197
8.6.2 弱引用的局限 199
8.7 Python 对不可变类型施加的把戏 199
8.8 本章小结 201
8.9 延伸阅读 201
第9章 符合 Python 风格的对象 205
9.1 对象表示形式 206
9.2 再谈向量类 206
9.3 备选构造方法 208
9.4 classmethod 与 staticmethod 209
9.5 格式化显示 210
9.6 可散列的 Vector2d 213
9.7 Python 的私有属性和“受保护的”属性 218
9.8 使用 __slots__ 类属性节省空间 220
9.9 覆盖类属性 222
9.10 本章小结 224
9.11 延伸阅读 225
第10章 序列的修改、散列和切片 229
10.1 Vector 类:用户定义的序列类型 230
10.2 Vector 类第1 版:与 Vector2d 类兼容 230
10.3 协议和鸭子类型 232
10.4 Vector 类第2 版:可切片的序列 233
10.4.1 切片原理 234
10.4.2 能处理切片的 __getitem__ 方法 236
10.5 Vector 类第3 版:动态存取属性 237
10.6 Vector 类第4 版:散列和快速等值测试 240
10.7 Vector 类第5 版:格式化 244
10.8 本章小结 251
10.9 延伸阅读 251
第11章 接口:从协议到抽象基类 256
11.1 Python 文化中的接口和协议 257
11.2 Python 喜欢序列 258
11.3 使用猴子补丁在运行时实现协议 260
11.4 Alex Martelli 的水禽 262
11.5 定义抽象基类的子类 266
11.6 标准库中的抽象基类 267
11.6.1 collections.abc 模块中的抽象基类 267
11.6.2 抽象基类的数字塔 269
11.7 定义并使用一个抽象基类 270
11.7.1 抽象基类句法详解 273
11.7.2 定义 Tombola 抽象基类的子类 274
11.7.3 Tombola 的虚拟子类 276
11.8 Tombola 子类的测试方法 278
11.9 Python 使用 register 的方式 281
11.10 鹅的行为有可能像鸭子 281
11.11 本章小结 283
11.12 延伸阅读 284
第12章 继承的优缺点 289
12.1 子类化内置类型很麻烦 289
12.2 多重继承和方法解析顺序 292
12.3 多重继承的真实应用 296
12.4 处理多重继承 298
12.5 一个现代示例:Django 通用视图中的混入 301
12.6 本章小结 304
12.7 延伸阅读 304
第13章 正确重载运算符 307
13.1 运算符重载基础 308
13.2 一元运算符 308
13.3 重载向量加法运算符 + 310
13.4 重载标量乘法运算符 * 315
13.5 众多比较运算符 318
13.6 增量赋值运算符 321
13.7 本章小结 325
13.8 延伸阅读 326
第五部分 控制流程
第14章 可迭代的对象、迭代器和生成器 330
14.1 Sentence 类第1 版:单词序列 331
14.2 可迭代的对象与迭代器的对比 334
14.3 Sentence 类第2 版:典型的迭代器 337
14.4 Sentence 类第3 版:生成器函数 339
14.5 Sentence 类第4 版:惰性实现 343
14.6 Sentence 类第5 版:生成器表达式 344
14.7 何时使用生成器表达式 345
14.8 另一个示例:等差数列生成器 346
14.9 标准库中的生成器函数 349
14.10 Python 3.3 中新出现的句法: yield from 357
14.11 可迭代的归约函数 358
14.12 深入分析 iter 函数 359
14.13 案例分析:在数据库转换工具中使用生成器 360
14.14 把生成器当成协程 362
14.15 本章小结 362
14.16 延伸阅读 363
第15章 上下文管理器和 else 块 368
15.1 先做这个,再做那个: if 语句之外的 else 块 369
15.2 上下文管理器和 with 块 370
15.3 contextlib 模块中的实用工具 374
15.4 使用 @contextmanager 375
15.5 本章小结 378
15.6 延伸阅读 378
第16章 协程 381
16.1 生成器如何进化成协程 382
16.2 用作协程的生成器的基本行为 382
16.3 示例:使用协程计算移动平均值 385
16.4 预激协程的装饰器 386
16.5 终止协程和异常处理 388
16.6 让协程返回值 391
16.7 使用 yield from 393
16.8 yield from 的意义 398
16.9 使用案例:使用协程做离散事件仿真 403
16.9.1 离散事件仿真简介 403
16.9.2 出租车队运营仿真 404
16.10 本章小结 410
16.11 延伸阅读 411
第17章 使用期物处理并发 416
17.1 示例:网络下载的三种风格 416
17.1.1 依序下载的脚本 418
17.1.2 使用 concurrent.futures 模块下载 420
17.1.3 期物在哪里 421
17.2 阻塞型 I/O 和 GIL 424
17.3 使用 concurrent.futures 模块启动进程 424
17.4 实验 Executor.map 方法 426
17.5 显示下载进度并处理错误 429
17.5.1 flags2 系列示例处理错误的方式 433
17.5.2 使用 futures.as_completed 函数 435
17.5.3 线程和多进程的替代方案 437
17.6 本章小结 437
17.7 延伸阅读 438
第18章 使用 asyncio 包处理并发 442
18.1 线程与协程对比 443
18.1.1 asyncio.Future :故意不阻塞 448
18.1.2 从期物、任务和协程中产出 449
18.2 使用 asyncio 和 aiohttp 包下载 450
18.3 避免阻塞型调用 454
18.4 改进 asyncio 下载脚本 456
18.4.1 使用 asyncio.as_completed 函数 456
18.4.2 使用 Executor 对象,防止阻塞事件循环 461
18.5 从回调到期物和协程 462
18.6 使用 asyncio 包编写服务器 466
18.6.1 使用 asyncio 包编写 TCP 服务器 467
18.6.2 使用 aiohttp 包编写 Web 服务器 471
18.6.3 更好地支持并发的智能客户端 474
18.7 本章小结 475
18.8 延伸阅读 476
第六部分 元编程
第19章 动态属性和特性 482
19.1 使用动态属性转换数据 483
19.1.1 使用动态属性访问 JSON 类数据 485
19.1.2 处理无效属性名 487
19.1.3 使用 __new__ 方法以灵活的方式创建对象 488
19.1.4 使用 shelve 模块调整 OSCON 数据源的结构 490
19.1.5 使用特性获取链接的记录 493
19.2 使用特性验证属性 498
19.2.1 LineItem 类第1 版:表示订单中商品的类 498
19.2.2 LineItem 类第2 版:能验证值的特性 499
19.3 特性全解析 500
19.3.1 特性会覆盖实例属性 501
19.3.2 特性的文档 503
19.4 定义一个特性工厂函数 504
19.5 处理属性删除操作 506
19.6 处理属性的重要属性和函数 507
19.6.1 影响属性处理方式的特殊属性 507
19.6.2 处理属性的内置函数 508
19.6.3 处理属性的特殊方法 509
19.7 本章小结 510
19.8 延伸阅读 510
第20章 属性描述符 514
20.1 描述符示例:验证属性 514
20.1.1 LineItem 类第3 版:一个简单的描述符 515
20.1.2 LineItem 类第4 版:自动获取储存属性的名称 519
20.1.3 LineItem 类第5 版:一种新型描述符 524
20.2 覆盖型与非覆盖型描述符对比 526
20.2.1 覆盖型描述符 528
20.2.2 没有 __get__ 方法的覆盖型描述符 529
20.2.3 非覆盖型描述符 530
20.2.4 在类中覆盖描述符 531
20.3 方法是描述符 531
20.4 描述符用法建议 533
20.5 描述符的文档字符串和覆盖删除操作 534
20.6 本章小结 535
20.7 延伸阅读 536
第21章 类元编程 538
21.1 类工厂函数 539
21.2 定制描述符的类装饰器 541
21.3 导入时和运行时比较 543
21.4 元类基础知识 547
21.5 定制描述符的元类 552
21.6 元类的特殊方法 __prepare__ 554
21.7 类作为对象 556
21.8 本章小结 557
21.9 延伸阅读 557
结语 560
附录 A 辅助脚本 563
Python 术语表 588
作者简介 600
关于封面 600
|
內容試閱:
|
前言
要不这样吧,如果编程语言里有个地方你弄不明白,而正好又有个人用了这个功能,那就开枪把他打死。这比学习新特性要容易些,然后过不了多久,那些活下来的程序员就会开始用0.9.6版的Python,而且他们只需要使用这个版本中易于理解的那一小部分就好了(眨眼)。1
Tim Peters传奇的核心开发者,Python之禅作者
Python官方教程(https:docs.python.org3tutorial)的开头是这样写的:Python是一门既容易上手又强大的编程语言。这句话本身并无大碍,但需要注意的是,正因为它既好学又好用,所以很多Python程序员只用到了其强大功能的一小部分。
只需要几个小时,经验丰富的程序员就能学会用Python写出实用的程序。然而随着这最初高产的几个小时变成数周甚至数月,在那些先入为主的编程语言的影响下,开发者们会慢慢地写出带着口音的Python代码。即便Python是你的初恋,也难逃此命运。因为在学校里,抑或是那些入门书上,教授者往往会有意避免只跟语言本身相关的特性。
另外,向那些已在其他语言领域里有了丰富经验的程序员介绍Python的时候,我还发现了一个问题:人们总是倾向于寻求自己熟悉的东西。受到其他语言的影响,你大概能猜到Python会支持正则表达式,然后就会去查阅文档。但是如果你从来没见过元组拆包(tuple unpacking),也没听过描述符(descriptor)这个概念,那么估计你也不会特地去搜索它们,然后就永远失去了使用这些Python独有的特性的机会。这也是本书试图解决的一个问题。
这本书并不是一本完备的Python使用手册,而是会强调Python作为编程语言独有的特性,这些特性或者是只有Python才具备的,或者是在其他大众语言里很少见的。Python语言核心以及它的一些库会是本书的重点。尽管Python的包索引现在已经有6万多个库了,而且其中很多都异常实用,但是我几乎不会提到Python标准库以外的包。
注1: 给comp.lang.python Usenet小组的留言,2002年12月23日,Acrimony in c.l.p(https:mail.python.orgpipermailpython-list2002-December147293.html)。
目标读者
本书的目标读者是那些正在使用Python,又想熟悉Python 3 的程序员。如果你懂Python 2, 但是想迁移到Python 3.4
或者更新的版本,也没问题。在写这本书的时候,大多数专业Python
程序员用的还是Python
2,因此如果书中出现来自Python
3 的特性,读者可能会感到陌生,我也会特别地做出解释。
然而,本书的主要目的是为了充分地展现Python
3.4 的魅力,因此我不会一字一句地说明如何让本书的代码在旧版本里正常运行。本书中的大多数例子稍做修改(甚至不用修改)
就可以在Python 2.7 里面跑起来,但是有些例子,如果追求向下兼容,就会需要大量的重写。
话虽如此,我还是认为,即便你无法从Python
2.7 里脱身,这本书也会对你很有帮助,因为Pyhon
语言的核心概念是不会变的。Python
3 也不是一门全新的语言,大多数的改动花一下午大概就能适应,官方文档里Python 3.0 的新特性一节(https:docs.python.
org3.0whatsnew3.0.html)就是很好的切入点。固然,自2009
年发布以来,Python 3.0
也在变化,但是这些变化比起Python
3.0 和Python
2.0 之间的区别,并没有那么重要。
如果你尚不清楚自己对Python
的熟悉程度能否跟得上本书的内容,建议你回头看看Python
的官方教程。注意,除非是跟Python
3 的新特性有关,教程里的其他内容本书不会重复。
非目标读者
如果你才刚刚开始学Python,本书的内容可能会显得有些超纲。比难懂更糟的是,如果在学习Python 的过程中过早接触本书的内容,你可能会误以为所有的Python
代码都应该利用特殊方法和元编程(metaprogramming)技巧。我们知道,不成熟的抽象和过早的优化一样,都会坏事。
本书的结构
如果你是本书的目标读者,那你应该可以从本书的任意一章开始阅读,但是如果按照我写作时的构思来的话,本书一共分为六个独立的部分,每个部分内的章节最好按照顺序来读。
在介绍让你自己实现某些功能的方法之前,我通常会先把现成可用的工具讲清楚。比如说第二部分的第2 章覆盖了序列类型(sequence
type),但是像collections.deque
这种类可能就会一带而过。一直到第四部分,我们才会看看如何从抽象基类(abstract
base class, ABC)中获利,抽象基类则被封装在collections.abc
这个包里。如果想创建自己的ABC,你可能得看到第四部分的最后一些内容才行,因为我一直觉得,如果没有熟练使用ABC
的经验,贸然去实现一套自己的东西是不合适的。
这样做有几个好处。第一,知道有什么现成的工具可用,能避免重新发明轮子。毕竟我们使用现有集合类型(collection type)的概率要远大于自己动手写一套新的。第二,这样一来,在讨论如何写新类型之前,我们能够有更多的机会来了解这些现成类的高级用法。第三,比起从零开始构建一个ABC,继承已有的ABC 库应该会简单一些。最后,我认为在看过一些实际的案例之后,理解抽象会更轻松。
当然,这样也会带来一些不便之处,比如书里的向前引用就会分散在各个不同的章节里面。但是经过上述这番梳理,我想这一点不便之处也是可以容忍的。
下面是本书每一部分的主题。
第一部分
第一部分只有单独的一章,讲解的是Python
的数据模型(data model),以及如何为了保证行为一致性而使用特殊方法(比如__repr__),毕竟Python 的一致性是出了名的。其实整本书几乎都是在讲解Python
的数据模型,第1 章算是一个概览。
第二部分
第二部分包含了各种集合类型:序列(sequence)、映射(mapping)和集合(set),另外还提及了字符串(str)和字节序列(bytes)的区分。说起来,最后这一点也是让亲者(Python
3 用户)快,仇者(Python
2 用户)痛的一个关键,因为这个区分致使Python
2 代码迁移到Python 3 的难度陡增。第二部分的目标是帮助读者回忆起Python
内置的类库,顺带解释这些类库的一些不太直观的地方。具体的例子有Python
3 如何在我们观察不到的地方对dict 的键重新排序,或者是排序有区域(locale)依赖的字符串时的注意事项。为了达到本部分的目标,有些地方的讲解会比较大而全,像序列类型和映射类型的变种就是这样;有时则会写得很深入,比方说我会对dict 和set 底层的散列表进行深层次的讨论。
第三部分
如何把函数作为一等对象(first-order
object)来使用。第三部分首先会解释前面这句话是什么意思,然后话题延伸到这个概念对那些被广泛使用的设计模型的影响,最后读者会看到如何利用闭包(closure)的概念来实现函数装饰器(function
decorator)。这一部分的话题还包括Python
的这些基本概念:可调用(callable)、函数属性(function
attribute)、内省(introspection)、参数注解(parameter
annotation)和Python
3 里新出现的nonlocal
声明。
第四部分
到了这里,书的重点转移到了类的构建上面。虽然在第二部分里的例子里就有类声明(class
declaration)的出现,但是第四部分会呈现更多的类。和任何面向对象语言一样,
Python 还有些自己的特性,这些特性可能并不会出现在你我学习基于类的编程的语言中。这一部分的章节解释了引用(reference)的原理、可变性的概念、实例的生命周期、如何构建自定义的集合类型和ABC、多重继承该怎么理顺、什么时候应该使用操作符重载及其方法。
第五部分
Python 中有些结构和库不再满足于诸如条件判断、循环和子程序(subroutine)之类的顺序控制流程,第五部分的笔墨会集中在这些构造和库上。我们会从生成器(generator)起步,然后话题会转移到上下文管理器(context manager)和协程(coroutine),其中会涵盖新增的功能强大但又不容易理解的yield from 语法。这一部分以并发性和面向事件的IO 来结尾,其中跟并发性相关的是collections.futures 这个很新的包,它借助futures 包把线程和进程的概念给封装了起来;而跟面向事件IO 相关的则是asyncio,它的背后是基于协程和yield from 的futures 包。
第六部分
第六部分的开头会讲到如何动态创建带属性的类,用以处理诸如JSON
这类半结构化的数据。然后会从大家已经熟悉的特性(property)机制入手,用描述符从底层来解释Python 对象属性的存取。同时,函数、方法和描述符的关系也会被梳理一遍。第六部分会从头至尾地实现一个字段验证器,在这个过程中我们会遇到一些微妙的问题,然后在最后一章中就自然引出像类装饰器(class
decorator)和元类(metaclass)这些高级的概念。
以实践为基础
一般情况下,我们会用Python
的交互式控制台来探索各种库和语言本身。有些读者可能对静态的需要编译的语言更熟悉,但是这些语言可能不会提供REPL(read-eval-print loop, 读取、求值、输出的循环)。在这里我想强调一下Python
交互式控制台,也就是REPL, 作为一个学习工具的重要性。
doctest(https:docs.python.org3librarydoctest.html)是Python 的一个标准库,做测试用的。这个库通过模拟控制台对话来检验表达式求值是否正确,而本书中几乎所有代码的测试,包括那些在控制台里的输出,都是通过这个库来进行的。doctest
看起来就像是Python 交互式控制台的剧本,你甚至都不需要了解它背后的运行机制就可以直接用它来试验书里的例子。
我有时为了事先说明一段代码的目的,会在展示代码之前先摆出相应的doctest
文本。这是因为我认为,在考虑如何实现一个功能之前,先严格地列出这个功能能做什么,这能帮助我们在编程时把精力花在该花的地方。测试驱动开发(TDD)的精髓就是先写测试,我后来发现这种精神在教学中也是大有益处的。如果你对doctest
还不熟悉,花点时间阅读它的文档(https:docs.python.org3librarydoctest.html)。结合本书的源码(https:github.
comfluentpythonexample-code),你可以在操作系统的控制台里键入python3 -m doctest example_script.py 来验证书中几乎所有代码的正确性。
硬件
书中有一些简单的时间和基准测试,跑这些测试的时候我用的是写书时的两台笔记本电脑。一台是产于2011 年的MacBook Pro 13 英寸笔记本,配置是2.7 GHz 的英特尔Core i7 处理器、8GB 的内存和机械硬盘;另一台是产于2014 年的MacBook Air 13 英寸笔记本, 配置是1.4 GHz 的英特尔Core i5 处理器、4GB 内存和一个固态硬盘。MacBook Air 的处理器虽然慢一些,内存也没有另一台多,但是它的内存快一些(1600 MHz,MacBook Pro 13 英寸则是1333 MHz),另外它的硬盘也更快,因此在日常使用中我并没有感觉到两台笔记本有速度上的差异。
杂谈:个人的一点看法
从1998
年起,我一直在使用Python,也做Python 教学,另外还一直在为它辩护。我一直都很享受这个过程,尤其是喜欢研究Python
同其他语言在设计和理论上的不同。因此在有些章节的最后,我会加上一点自己对Python
以及其他语言的看法,我把这部分叫作杂谈。如果你对这些东西不感兴趣,跳过即可,因为这些并不是必读的。
Python术语表
我希望这本书不仅仅是关于Python
的,也是关于Python 的文化的。在过去20 多年的交流中,Python 社区形成了它独有的行话和缩写。本书的最后有一部分叫Python 术语表, 里面列出了在Python
爱好者中具有特别意义的词句。
Python版本表
本书所有的代码都在Python
3.4 里测试过,而且是应用最广的用C 实现的CPython
3.4。只有一个例外,在13.4
节中的Python 3.5 新引入的中缀运算符@附注栏里,我提到了新的@ 运算符,它只在Python 3.5
里被支持。
凡是支持Python
3.x 的解释器包括PyPy3 2.4.0都可以运行书里的代码(PyPy3 2.4.0 其实已经支持Python 3.2.5)。有一点需要注意的是,yield from 和asyncio 只在Python 3.3 或者更新的版本里才有。
几乎所有的代码稍做修改后都能在Python 2.7 里运行,除了第4 章中那些跟Unicode 相关的例子,这是从Python 3 出现以来就有的问题。
排版约定
本书使用了下列排版约定。
楷体
表示新术语。
等宽字体(constant width)
表示程序片段,以及正文中出现的变量、函数名、数据库、数据类型、环境变量、语句和关键字等。
加粗等宽字体(constant
width bold)
表示应该由用户输入的命令或其他文本。
等宽斜体(Constant
width italic)
表示应该由用户输入的值或根据上下文确定的值替换的文本。
该图标表示提示或建议。
该图标表示一般注记。
该图标表示警告或警示。
使用代码示例
书中的所有完整代码和大多数程序片段都可以从本书的GitHub
代码库中获取(https:
github.comfluentpythonexample-code)。
我们很希望但并不强制要求你在引用本书内容时加上引用说明。引用说明一般包括书名、作者、出版社和ISBN。比如:Fluent
Python by
Luciano Ramalho OReilly. Copyright 2015
Luciano Ramalho, 978-1-491-94600-8.
SafariBooks Online
Safari Books Online(http:www.safaribooksonline.com)是应运而生的数字图书馆。它同时以图书和视频的形式出版世界顶级技术和商务作家的专业作品。
技术专家、软件开发人员、Web 设计师、商务人士和创意专家等,在开展调研、解决问题、学习和认证培训时,都将Safari Books Online 视作获取资料的首选渠道。
对于组织团体、政府机构和个人,Safari Books Online 提供各种产品组合和灵活的定价策略。用户可通过一个功能完备的数据库检索系统访问OReilly Media、Prentice Hall
Professional、Addison-Wesley Professional、Microsoft Press、Sams、Que、Peachpit Press、Focal Press、Cisco Press、John Wiley & Sons、Syngress、Morgan Kaufmann、IBM Redbooks、Packt、Adobe Press、FT Press、Apress、Manning、New Riders、McGraw-Hill、Jones & Bartlett、Course Technology 以及其他几十家出版社的上千种图书、培训视频和正式出版之前的书稿。要了解Safari Books Online 的更多信息,我们网上见。
联系我们
请把对本书的评价和问题发给出版社。
美国:
OReilly
Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
中国:
北京市西城区西直门南大街2 号成铭大厦C 座807 室(100035)
奥莱利技术咨询(北京)有限公司
OReilly 的每一本书都有专属网页,你可以在那里找到本书的相关信息,包括勘误表、示例以及其他信息。本书的网站地址是:http:shop.oreilly.comproduct0636920032519.do
对于本书的评论和技术性问题,请发送电子邮件到:bookquestions@oreilly.com
要了解更多OReilly
图书、培训课程、会议和新闻的信息,请访问以下网站:http:www.
oreilly.com
我们在Facebook
的地址如下:http:facebook.comoreilly
请关注我们的Twitter
动态:http:twitter.comoreillymedia
我们的YouTube
视频地址如下:http:www.youtube.comoreillymedia
致谢
Josef Hartwig 设计的包豪斯国际象棋套装体现了最佳的设计理念:美观、简洁而清晰。有一位建筑师父亲,以及一位字体设计师弟弟,Guido
van Rossum 设计出了一门经典的编程语言。我之所以热衷于教授Python,也正是因为它的美观、简洁和清晰。
Alex Martelli 和Anna Ravenscroft 是最先看到本书大纲的人,也是他们鼓励我把大纲交给OReilly
出版社的。他们的书不但向我展示了地道的Python
代码,还让我见识了什么才称得上是清晰、准确和有深度的技术写作。Alex
在Stack
Overflow 上的5000
多个回答(http:stackoverflow.comusers95810alex-martelli)也体现了他对Python 语言基础和正确用法的深入理解。
Martelli 和Ravenscroft 同时也是本书的技术审稿人。除了他们之外,技术审稿人还有两位: Lennart
Regebro 和Leonardo
Rochael。技术审稿团队里的每个人都至少有15
年的Python 经验,为许许多多具有广泛影响力的Python 项目贡献过代码,并且跟社区里的其他开发者走得很近。审稿人一共提出了数百个修订、建议、问题和观点,为这本书做出了巨大贡献。另外,Victor
Stinner 帮我审阅了第18
章,他同时也是该章里提到的asyncio 的维护者之一。在过去的几个月里能够跟他们合作,我感到很荣幸。
本书编辑Meghan Blanchette 是一位出色的导师。她不但帮助我梳理整本书的结构、增强内容的连贯性,还为我指出哪里写得不够有趣,并且督促我及时交稿。Brian MacDonald 在Meghan 休假的时候帮忙编辑了第三部分。跟他们以及OReilly 的所有人打交道的过程都十分愉快。另外Atlas 系统的开发和支持团队也很棒(Atlas 是OReilly 的图书出版平台,
我就是在这个平台上写作的)。
Mario Domenech Goulart 在看过本书第一次提前发行的版本后,提供了海量的详细建议。另外我还从Dave
Pawson、Elias
Dorneles、Leonardo
Alexandre Ferreira Leite、Bruce
Eckel、J.
S. Bueno、Rafael
Gonalves、Alex Chiaranda、Guto Maia、Lucas Vido 和Lucas Brunialti 那里获得了宝贵的反馈。
几年来有很多人都在劝我写书,Rubens
Prates、Aurelio
Jargas、Rud Moura 和Rubens
Altimari 这几位算是最有说服力的了。Mauricio
Bussab 算得上带我入门的人,并且他让我有了第一次写书的尝试。Renzo
Nuccitelli 毫不在乎这本书的写作可能会影响到我们合作的python.pro.br
项目的进度,他从一开始就大力支持。
Python 巴西社区是一个集思广益、乐于分享且充满乐趣的地方。Python 巴西小组(https:
groups.google.comgrouppython-brasil)中有数千个人,每次的全国范围的会议都会把成百上千人聚集在一起。在我的Python
爱好者成长之路上,对我影响最大的人有:Leonardo
Rochael、Adriano
Petrich、Daniel
Vainsencher、Rodrigo
RBP Pimentel、Bruno
Gola、Leonardo
Santagada、Jean
Ferri、Rodrigo
Senra、J.
S. Bueno、David
Kwast、Luiz
Irber、Osvaldo
Santana、Fernando
Masanori、Henrique
Bastos、Gustavo
Niemayer、Pedro
Werneck、Gustavo
Barbieri、Lalo
Martins、Danilo
Bellini 和Pedro
Kroger。
Dorneles Tremea 是个非常棒的朋友(他很愿意花时间分享他的知识),他不但是很厉害的开发者,还是巴西Python
协会中最鼓舞人心的领导人。可惜他过早离开了我们。
我的学生们同时也是我的老师,他们的问题、见解、反馈和那些富有创造性的回答教会了我很多。rico
Andrei 和Simples
Consultoria 让我头一次有机会集中精力做一名Python
教师。
Martijn Faassen 是我的Grok 导师,他同我分享了很多关于Python 和尼安德特人的想法。Martijn 所做的事情,还有来自Zope、Plone 和Pyramid planets 的Paul Everitt、Chris McDonough、Tres Seaver、Jim Fulton、Shane Hathaway、Lennart Regebro、Alan Runyan、Alexander Limi、Martijn Pieters 和Godefroid Chapelle 等人所做的事情,在我事业发展的过程中起到了决定性的作用。多亏了Zope
和第一波互联网浪潮,让我在1998
年就开始从事Python 相关的工作并以此为生。Jos Octavio Castro Neves 是我的搭档,我们在巴西开了第一家以Python 业务为主的软件公司。
在更广阔的Python
社区当中高手如云,我实在是没办法一一列出他们的名字。但是除了之前提到的之外,我还要感谢Steve
Holden、Raymond
Hettinger、A.M.
Kuchling、David
Beazley、Fredrik
Lundh、Doug
Hellmann、Nick
Coghlan、Mark
Pilgrim、Martijn
Pieters、Bruce
Eckel、Michele
Simionato、Wesley
Chun、Brandon
Craig Rhodes、Philip
Guo、Daniel
Greenfeld、Audrey
Roy 和Brett
Slatkin,感谢他们让我见识到更新更好的教授Python
的方法。
我基本上是在家里的办公室和两个公共空间完成这本书的写作的。两个公共空间分别是CoffeeLab
和Garoa
Hacker Clube。CoffeeLab(http:coffeelab.com.br)是位于巴西圣保罗Vila
Madalena 区的一个咖啡极客大本营。Garoa
Hacker Clube(https:garoa.net.br)则是一个开放的黑客空间,任何人都可以在这里实验他们的新点子。
Garoa 社区还为我提供了灵感、基础设施和放松的环境,我想Aleph 会喜欢这本书的。
我的母亲Maria
Lucia 和父亲Jairo
一直都以各种方式支持我。我真希望我的父亲还健在并看到本书的出版,同时也为能与我的母亲分享这本书而感到开心。
在写这本书的15
个月里,身为丈夫的我几乎一直在工作,我的妻子Marta
Mello 陪我一起熬过了这段日子。在这如同跑马拉松的写作过程中,她不但一直支持我,而且在我想要放弃的时候陪我一起渡过难关。
谢谢你们每一个人,谢谢你们做的每一件事。
|
|