前言
要不这样吧,如果编程语言里有个地方你弄不明白,而正好又有个人用了这个功能,那就开枪把他打死。这比学习新特性要容易些,然后过不了多久,那些活下来的程序员就会开始用0.9.6版的Python,而且他们只需要使用这个版本中易于理解的那一小部分就好了(眨眼)。1
—— Tim Peters传奇的核心开发者,“Python之禅”作者
Python官方教程(https://docs.python.org/3/tutorial/)的开头是这样写的:“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.org/pipermail/python-list/2002-December/147293.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. org/3.0/whatsnew/3.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 语法。这一部分以并发性和面向事件的I/O 来结尾,其中跟并发性相关的是collections.futures 这个很新的包,它借助futures 包把线程和进程的概念给封装了起来;而跟面向事件I/O 相关的则是asyncio,它的背后是基于协程和yield from 的futures 包。
第六部分
第六部分的开头会讲到如何动态创建带属性的类,用以处理诸如JSON 这类半结构化的数据。然后会从大家已经熟悉的特性(property)机制入手,用描述符从底层来解释Python 对象属性的存取。同时,函数、方法和描述符的关系也会被梳理一遍。第六部分会从头至尾地实现一个字段验证器,在这个过程中我们会遇到一些微妙的问题,然后在最后一章中就自然引出像类装饰器(class decorator)和元类(metaclass)这些高级的概念。
……
标签
Python,编程,计算机,python,程序设计,图灵社区,自然科学