编辑推荐

  《流畅的Python》由奋战在Python开发一线近20年的LucianoRamalho执笔,VictorStinner、AlexMartelli等Python大咖担纲技术审稿人,从语言设计层面剖析编程细节,兼顾Python3和Python2,告诉你Python中不亲自动手实践就无法理解的语言陷阱成因和解决之道,教你写出风格地道的Python代码。
  ●Python数据模型:理解为什么特殊方法是对象行为一致的关键。
  ●数据结构:充分利用内置类型,理解Unicode文本和字节二象性。
  ●把函数视作对象:把Python函数视作一等对象,并了解这一点对流行的设计模式的影响。
  ●面向对象习惯用法:通过构建类学习引用、可变性、接口、运算符重载和多重继承。
  ●控制流程:学习使用上下文管理器、生成器、协程,以及通过concurrent.futures和asyncio包实现的并发。
  ●元编程:理解特性、描述符、类装饰器和元类的工作原理。

内容简介

  《流畅的Python》致力于帮助Python开发人员挖掘这门语言及相关程序库的优秀特性,避免重复劳动,同时写出简洁、流畅、易读、易维护,并且具有地道Python风格的代码。《流畅的Python》尤其深入探讨了Python语言的高级用法,涵盖数据结构、Python风格的对象、并行与并发,以及元编程等不同的方面。

作者简介

  LucianoRamalho,从1998年起就成为了Python程序员。他是Python软件基金会的成员,Python.pro.br(巴西的一家培训公司)的共同所有者,还是巴西众创空间GaroaHackerClube的联合创始人。他领导过多个软件开发团队,还在巴西的媒体、银行和政府部门教授Python课程。

  安道,专注于现代计算机技术的自由翻译,译有《FlaskWeb开发》《Python网络编程攻略》《RubyonRails教程》等书。

  吴珂,现为Airbnb公司软件工程师,所在团队主要负责开发和维护各类可伸缩、高性能服务,并在Airbnb内推广面向服务的系统架构。在分布式系统、云存储服务和跨平台SDK开发,以及大规模数据处理等方面有多年经验。

精彩书评

  “很荣幸担任这本优秀图书的技术审校。这《流畅的Python》能帮助很多中级Python程序员掌握这门语言,我也从中学到了相当多的知识!”
  ——AlexMartelli,Python软件基金会成员

  “对于想要扩充知识的中级和高级Python程序员来说,这《流畅的Python》是充满了实用编程技巧的宝藏。”
  ——Daniel和AudreyRoyGreenfeld,TwoScoopsofDjango作者

目录

前言  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.3 元组不仅仅是不可变的列表  22

2.4 切片  28

2.5 对序列使用+和*  31

2.6 序列的增量赋值  33

2.7 list.sort方法和内置函数sorted  36

2.8 用bisect来管理已排序的序列  37

2.9 当列表不是首选时  41

2.10 本章小结  49

2.11 延伸阅读  50

第3章 字典和集合  54

3.1 泛映射类型  54

3.2 字典推导  56

3.3 常见的映射方法  57

3.4 映射的弹性键查询  61

3.5 字典的变种  65

3.6 子类化UserDict  65

3.7 不可变映射类型  67

3.8 集合论  68

3.9 dict和set的背后  73

3.10 本章小结  80

3.11 延伸阅读  81

第4章 文本和字节序列  83

4.1 字符问题  84

4.2 字节概要  85

4.3 基本的编解码器  88

4.4 了解编解码问题  89

4.5 处理文本文件  94

4.6 为了正确比较而规范化Unicode字符串  99

4.7 Unicode文本排序  105

4.8 Unicode数据库  108

4.9 支持字符串和字节序列的双模式API  109

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.11 本章小结  137

5.12 延伸阅读  137

第6章 使用一等函数实现设计模式  141

6.1 案例分析:重构“策略”模式  142

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.9 叠放装饰器  172

7.10 参数化装饰器  173

7.11 本章小结  177

7.12 延伸阅读  178

第四部分 面向对象惯用法

第8章 对象引用、可变性和垃圾回收  182

8.1 变量不是盒子  183

8.2 标识、相等性和别名  184

8.3 默认做浅复制  187

8.4 函数的参数作为引用时  190

8.5 del和垃圾回收  195

8.6 弱引用  196

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.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 AlexMartelli的水禽  262

11.5 定义抽象基类的子类  266

11.6 标准库中的抽象基类  267

11.7 定义并使用一个抽象基类  270

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中新出现的句法:yieldfrom  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 使用yieldfrom  393

16.8 yieldfrom的意义  398

16.9 使用案例:使用协程做离散事件仿真  403

16.10 本章小结  410

16.11 延伸阅读  411

第17章 使用期物处理并发  416

17.1 示例:网络下载的三种风格  416

17.2 阻塞型I/O和GIL  424

17.3 使用concurrent.futures模块启动进程  424

17.4 实验Executor.map方法  426

17.5 显示下载进度并处理错误  429

17.6 本章小结  437

17.7 延伸阅读  438

第18章 使用asyncio包处理并发  442

18.1 线程与协程对比  443

18.2 使用asyncio和aiohttp包下载  450

18.3 避免阻塞型调用  454

18.4 改进asyncio下载脚本  456

18.5 从回调到期物和协程  462

18.6 使用asyncio包编写服务器  466

18.7 本章小结  475

18.8 延伸阅读  476

第六部分 元编程

第19章 动态属性和特性  482

19.1 使用动态属性转换数据  483

19.2 使用特性验证属性  498

19.3 特性全解析  500

19.4 定义一个特性工厂函数  504

19.5 处理属性删除操作  506

19.6 处理属性的重要属性和函数  507

19.7 本章小结  510

19.8 延伸阅读  510

第20章 属性描述符  514

20.1 描述符示例:验证属性  514

20.2 覆盖型与非覆盖型描述符对比  526

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
  ——TimPeters传奇的核心开发者,“Python之禅”作者
  Python官方教程(https://docs.python.org/3/tutorial/)的开头是这样写的:“Python是一门既容易上手又强大的编程语言。”这句话本身并无大碍,但需要注意的是,正因为它既好学又好用,所以很多Python程序员只用到了其强大功能的一小部分。
  只需要几个小时,经验丰富的程序员就能学会用Python写出实用的程序。然而随着这最初高产的几个小时变成数周甚至数月,在那些先入为主的编程语言的影响下,开发者们会慢慢地写出带着“口音”的Python代码。即便Python是你的初恋,也难逃此命运。因为在学校里,抑或是那些入门书上,教授者往往会有意避免只跟语言本身相关的特性。
  另外,向那些已在其他语言领域里有了丰富经验的程序员介绍Python的时候,我还发现了一个问题:人们总是倾向于寻求自己熟悉的东西。受到其他语言的影响,你大概能猜到Python会支持正则表达式,然后就会去查阅文档。但是如果你从来没见过元组拆包(tupleunpacking),也没听过描述符(descriptor)这个概念,那么估计你也不会特地去搜索它们,然后就永远失去了使用这些Python独有的特性的机会。这也是《流畅的Python》试图解决的一个问题。
  这《流畅的Python》并不是一本完备的Python使用手册,而是会强调Python作为编程语言独有的特性,这些特性或者是只有Python才具备的,或者是在其他大众语言里很少见的。Python语言核心以及它的一些库会是《流畅的Python》的重点。尽管Python的包索引现在已经有6万多个库了,而且其中很多都异常实用,但是我几乎不会提到Python标准库以外的包。
  注1:给comp.lang.pythonUsenet小组的留言,2002年12月23日,“Acrimonyinc.l.p”(https://mail.python.org/pipermail/python-list/2002-December/147293.html)。
  目标读者
  《流畅的Python》的目标读者是那些正在使用Python,又想熟悉Python3的程序员。如果你懂Python2,但是想迁移到Python3.4或者更新的版本,也没问题。在写这《流畅的Python》的时候,大多数专业Python程序员用的还是Python2,因此如果书中出现来自Python3的特性,读者可能会感到陌生,我也会特别地做出解释。
  然而,《流畅的Python》的主要目的是为了充分地展现Python3.4的魅力,因此我不会一字一句地说明如何让《流畅的Python》的代码在旧版本里正常运行。《流畅的Python》中的大多数例子稍做修改(甚至不用修改)就可以在Python2.7里面跑起来,但是有些例子,如果追求向下兼容,就会需要大量的重写。
  话虽如此,我还是认为,即便你无法从Python2.7里脱身,这《流畅的Python》也会对你很有帮助,因为Pyhon语言的核心概念是不会变的。Python3也不是一门全新的语言,大多数的改动花一下午大概就能适应,官方文档里“Python3.0的新特性”一节(https://docs.python.org/3.0/whatsnew/3.0.html)就是很好的切入点。固然,自2009年发布以来,Python3.0也在变化,但是这些变化比起Python3.0和Python2.0之间的区别,并没有那么重要。
  如果你尚不清楚自己对Python的熟悉程度能否跟得上《流畅的Python》的内容,建议你回头看看Python的官方教程。注意,除非是跟Python3的新特性有关,教程里的其他内容《流畅的Python》不会重复。
  非目标读者
  如果你才刚刚开始学Python,《流畅的Python》的内容可能会显得有些“超纲”。比难懂更糟的是,如果在学习Python的过程中过早接触《流畅的Python》的内容,你可能会误以为所有的Python代码都应该利用特殊方法和元编程(metaprogramming)技巧。我们知道,不成熟的抽象和过早的优化一样,都会坏事。
  《流畅的Python》的结构
  如果你是《流畅的Python》的目标读者,那你应该可以从《流畅的Python》的任意一章开始阅读,但是如果按照我写作时的构思来的话,《流畅的Python》一共分为六个独立的部分,每个部分内的章节最好按照顺序来读。
  在介绍让你自己实现某些功能的方法之前,我通常会先把现成可用的工具讲清楚。比如说第二部分的第2章覆盖了序列类型(sequencetype),但是像collections.deque这种类可能就会一带而过。一直到第四部分,我们才会看看如何从抽象基类(abstractbaseclass,ABC)中获利,抽象基类则被封装在collections.abc这个包里。如果想创建自己的ABC,你可能得看到第四部分的最后一些内容才行,因为我一直觉得,如果没有熟练使用ABC的经验,贸然去实现一套自己的东西是不合适的。
  这样做有几个好处。第一,知道有什么现成的工具可用,能避免重新发明轮子。毕竟我们使用现有集合类型(collectiontype)的概率要远大于自己动手写一套新的。第二,这样一来,在讨论如何写新类型之前,我们能够有更多的机会来了解这些现成类的高级用法。第三,比起从零开始构建一个ABC,继承已有的ABC库应该会简单一些。最后,我认为在看过一些实际的案例之后,理解抽象会更轻松。
  当然,这样也会带来一些不便之处,比如书里的向前引用就会分散在各个不同的章节里面。但是经过上述这番梳理,我想这一点不便之处也是可以容忍的。
  下面是《流畅的Python》每一部分的主题。
  第一部分
  第一部分只有单独的一章,讲解的是Python的数据模型(datamodel),以及如何为了保证行为一致性而使用特殊方法(比如__repr__),毕竟Python的一致性是出了名的。其实整《流畅的Python》几乎都是在讲解Python的数据模型,第1章算是一个概览。
  第二部分
  第二部分包含了各种集合类型:序列(sequence)、映射(mapping)和集合(set),另外还提及了字符串(str)和字节序列(bytes)的区分。说起来,最后这一点也是让亲者(Python3用户)快,仇者(Python2用户)痛的一个关键,因为这个区分致使Python2代码迁移到Python3的难度陡增。第二部分的目标是帮助读者回忆起Python内置的类库,顺带解释这些类库的一些不太直观的地方。具体的例子有Python3如何在我们观察不到的地方对dict的键重新排序,或者是排序有区域(locale)依赖的字符串时的注意事项。为了达到本部分的目标,有些地方的讲解会比较大而全,像序列类型和映射类型的变种就是这样;有时则会写得很深入,比方说我会对dict和set底层的散列表进行深层次的讨论。
  第三部分
  如何把函数作为一等对象(first-orderobject)来使用。第三部分首先会解释前面这句话是什么意思,然后话题延伸到这个概念对那些被广泛使用的设计模型的影响,最后读者会看到如何利用闭包(closure)的概念来实现函数装饰器(functiondecorator)。这一部分的话题还包括Python的这些基本概念:可调用(callable)、函数属性(functionattribute)、内省(introspection)、参数注解(parameterannotation)和Python3里新出现的nonlocal声明。
  第四部分
  到了这里,书的重点转移到了类的构建上面。虽然在第二部分里的例子里就有类声明(classdeclaration)的出现,但是第四部分会呈现更多的类。和任何面向对象语言一样,Python还有些自己的特性,这些特性可能并不会出现在你我学习基于类的编程的语言中。这一部分的章节解释了引用(reference)的原理、“可变性”的概念、实例的生命周期、如何构建自定义的集合类型和ABC、多重继承该怎么理顺、什么时候应该使用操作符重载及其方法。
  第五部分
  Python中有些结构和库不再满足于诸如条件判断、循环和子程序(subroutine)之类的顺序控制流程,第五部分的笔墨会集中在这些构造和库上。我们会从生成器(generator)起步,然后话题会转移到上下文管理器(contextmanager)和协程(coroutine),其中会涵盖新增的功能强大但又不容易理解的yieldfrom语法。这一部分以并发性和面向事件的I/O来结尾,其中跟并发性相关的是collections.futures这个很新的包,它借助futures包把线程和进程的概念给封装了起来;而跟面向事件I/O相关的则是asyncio,它的背后是基于协程和yieldfrom的futures包。
  第六部分
  第六部分的开头会讲到如何动态创建带属性的类,用以处理诸如JSON这类半结构化的数据。然后会从大家已经熟悉的特性(property)机制入手,用描述符从底层来解释Python对象属性的存取。同时,函数、方法和描述符的关系也会被梳理一遍。第六部分会从头至尾地实现一个字段验证器,在这个过程中我们会遇到一些微妙的问题,然后在最后一章中就自然引出像类装饰器(classdecorator)和元类(metaclass)这些高级的概念。
  ……

其他推荐