Home

Fluent Python 笔记 第 12 章 继承的优缺点

重点是说明对 Python 而言尤为重要的两个细节: 子类化内置类型的缺点 多重继承和方法解析顺序 12.1 子类化内置类型很麻烦 内置类型(使用 C 语言编写)不会调用用户定义的类覆盖的特殊方法。 不要子类化内置类型,用户自己定义的类应 该继承 collections 模块(http://docs.python.org/3/library/collections.html)中的类,例如 UserDict、UserList 和 UserString,这些类做了特殊设计,因此易于扩展。 12.2 多重继承和方法解析顺序 两种调用方法: d.pong() pong: <diamond.D object at 0x10066c278> C.pong(d) A....

Read more

Fluent Python 笔记 第 11 章 接口:从协议到抽象基类

本章讨论的话题是接口:从鸭子类型的代表特征动态协议,到使接口更明确、能验证实现是否符合规定的抽象基类(Abstract Base Class,ABC)。 11.1 Python 文化中的接口和协议 对 Python 程序员来说,“X 类对象”“X 协 议”和“X 接口”都是一个意思。 11.2 Python 喜欢序列 Python 数据模型的哲学是尽量支持基本协议。 为了迭代对象,解释器会尝试调用两个不同的方法。 11.3 使用猴子补丁在运行时实现协议 shuffle 函数要调换集合中元素的位置,而 FrenchDeck 只实现了不可变的序列协议。可变的序列还必须提供 __setitem__ 方法。 >>> def set_card(deck, positio...

Read more

Fluent Python 笔记 第 10 章 序列的修改、散列和切片

本章将以第 9 章定义的二维向量 Vector2d 类为基础,向前迈出一大步,定义表示多维向量的 Vector 类。这个类的行为与 Python 中标准的不可变扁平序列一样。 10.3 协议和鸭子类型 在 Python 中创建功能完善的序列类型无需使用继承,只需实现符合序列协议的方法。 Python 的序列协议只需要 __len__ 和 __getitem__ 两个方法。任何类(如 Spam),只要使用标准的签名和语义实现了这两个方法,就能用在任何期待序列的地方。 10.4 Vector类第2版:可切片的序列 10.4.1 切片原理 S.indices(len) -> (start, stop, stride) 给定长度为 len 的序列,计算 S 表示的扩展切片的起始(...

Read more

Fluent Python 笔记 第 8 章 对象引用、可变性和垃圾回收

本章先以一个比喻说明 Python 的变量:变量是标注,而不是盒子。如果你不知道引用式变量是什么,可以像这样对别人解释别名。 然后,本章讨论对象标识、值和别名等概念。随后,本章会揭露元组的一个神奇特性:元组是不可变的,但是其中的值可以改变,之后就引申到浅复制和深复制。接下来的话题是引用和函数参数:可变的参数默认值导致的问题,以及如何安全地处理函数的调用者传入的可变参数。 本章最后一节讨论垃圾回收、del 命令,以及如何使用弱引用“记住”对象,而无需对象本身存在。 本章的内容有点儿枯燥,但是这些话题却是解决 Python 程序中很多不易察觉的 bug 的关键。 首先,我们要抛弃变量是存储数据的盒子这一错误观念。 8.1 变量不是盒子 a = [1, 2, 3] b = a a.a...

Read more

Fluent Python 笔记 第 7 章 函数装饰器和闭包

函数装饰器用于在源码中“标记”函数,以某种方式增强函数的行为。这是一项强大的功能,但是若想掌握,必须理解闭包。 nonlocal 是新近出现的保留关键字,在 Python 3.0 中引入。作为 Python 程序员,如果严格 遵守基于类的面向对象编程方式,即便不知道这个关键字也不会受到影响。然而,如果你想自己实现函数装饰器,那就必须了解闭包的方方面面,因此也就需要知道 nonlocal。 除了在装饰器中有用处之外,闭包还是回调式异步编程和函数式编程风格的基础。 本章的最终目标是解释清楚函数装饰器的工作原理,包括最简单的注册装饰器和较复杂的参数化装饰器。但是,在实现这一目标之前,我们要讨论下述话题: Python 如何计算装饰器句法 Python 如何判断变量是不是局部的...

Read more

Fluent Python 笔记 第 6 章 使用一等函数实现设计模式

虽然设计模式与语言无关,但这并不意味着每一个模式都能在每一门语言中使用。1996 年,Peter Norvig 在题为“Design Patterns in Dynamic Languages”(http://norvig.com/design- patterns/)的演讲中指出,Gamma 等人合著的《设计模式:可复用面向对象软件的基础》一 书中有 23 个模式,其中有 16 个在动态语言中“不见了,或者简化了”(参见第 9 张幻灯片)。他讨论的是 Lisp 和 Dylan,不过很多相关的动态特性在 Python 中也能找到。具体而言,Norvig 建议在有一等函数的语言中重新审视“策略”“命令”“模板方法”和“访问者”模式。通常,我们可以把这些模式中涉及的某些类的实例替换成简单的函...

Read more

Fluent Python 笔记 第 5 章 一等函数

在 Python 中,函数是一等对象。编程语言理论家把“一等对象”定义为满足下述条件的程 序实体: 在运行时创建 能赋值给变量或数据结构中的元素 • 能作为参数传给函数 能作为函数的返回结果 5.1 把函数视作对象 会用 map。 5.2 高阶函数 接受函数为参数,或者把函数作为结果返回的函数是高阶函数(higher-order function)。 map、filter 和 reduce 的现代替代品 >>> list(map(fact, range(6))) [1, 1, 2, 6, 24, 120] >>> [fact(n) for n in range(6)] [1, 1, 2, 6, 24, 120] >>...

Read more

Fluent Python 笔记 第 4 章 文本和字节序列

Python 3 明确区分了人类可读的文本字符串和原始的字节序列。隐式地把字节序列转换成 Unicode 文本已成过去。本章将要讨论 Unicode 字符串、二进制序列,以及在二者之间转 换时使用的编码。 没啥可看的,就一句话,一定不能依赖默认编码,传参数 utf-8。 4.1 字符问题 >>> s = 'café' >>> len(s) 4 >>> b = s.encode('utf8') >>> b b'caf\xc3\xa9' >>> len(b) 5 >>> b.decode('utf8') 'café' 4.2 字节概要 4.3 基本的编解码器 4.4 了解...

Read more