Home

Fluent Python 笔记 第 19 章 动态属性和特性

在 Python 中,数据的属性和处理数据的方法统称属性(attribute)。其实,方法只是可调用的属性。 19.1 使用动态属性转换数据 from collections import abc class FrozenJSON: """一个只读接口,使用属性表示法访问JSON类对象 """ def __init__(self, mapping): self.__data = dict(mapping) def __getattr__(self, name): if hasattr(self.__data, name): return getattr(self.__data, name) e...

Read more

Fluent Python 笔记 第 18 章 使用 asyncio 包处理并发

本章介绍 asyncio 包,这个包使用事件循环驱动的协程实现并发。 18.1 线程与协程对比 Python 没有提供终止线程的 API,这是有意为之的。若想关闭线程,必须给线程发送消息。 交给 asyncio 处理的协程要使用 @asyncio.coroutine 装饰。这不是强制要求,但是强烈建议这么做。因为这样能在一众普通的函数中把协程凸显出来,也有助于调试:如果还没从中产出值,协程就被垃圾回收了(意味着有操作未完成,因此有可能是个缺陷),那就可以发出警告。这个装饰器不会预激协程。 使用 yield from asyncio.sleep(.1) 代替 time.sleep(.1),这样的休眠不会阻塞事件循环。 asyncio.Task 对象差不多与 threadin...

Read more

Fluent Python 笔记 第 17 章 使用 future 处理并发

future 指一种对象,表示异步执行的操作。这个概念的作用很大,是 concurrent.futures 模块和 asyncio 包(第 18 章讨论)的基础。 17.1 示例:网络下载的三种风格 17.1.1 依序下载的脚本 17.1.2 使用 concurrent.futures 模块下载 from concurrent import futures workers = min(MAX_WORKERS, len(cc_list)) with futures.ThreadPoolExecutor(workers) as executor: res = executor.map(download_one, sorted(cc_list)) 17.1.3 future 在...

Read more

Fluent Python 笔记 第 16 章 协程

从句法上看,协程与生成器类似,都是定义体中包含 yield 关键字的函数。可是,在协程中,yield通常出现在表达式的右边(例如,datum = yield),可以产出值,也可以不产出——如果 yield 关键字后面没有表达式,那么生成器产出 None。协程可能会从调用方接收数据,不过调用方把数据提供给协程使用的是 .send(datum) 方法,而不是 next(…) 函数。通常,调用方会把值推送给协程。 yield 关键字甚至还可以不接收或传出数据。不管数据如何流动,yield 都是一种流程控制 工具,使用它可以实现协作式多任务:协程可以把控制器让步给中心调度程序,从而激活 其他的协程。 从根本上把 yield 视作控制流程的方式,这样就好理解协程了。 16.1 生成器如何进...

Read more

Fluent Python 笔记 第 15 章 上下文管理器和 else 块

15.1 先做这个,再做那个:if语句之外的else块 else 子句不仅能在 if 语句中使用,还能在 for、while 和 try 语句中使用。 for 仅当 for 循环运行完毕时(即 for 循环没有被 break 语句中止)才运行 else 块。 while 仅当 while 循环因为条件为假值而退出时(即 while 循环没有被 break 语句中止)才运行 else 块。 try 仅当 try 块中没有异常抛出时才运行 else 块。官方文档(https://docs.python.org/3/ reference/compound_stmts.html)还指出:“else 子句抛出的异常不会由前面的 except 子句处理。” 15.2 上下文管理器和wit...

Read more

Fluent Python 笔记 第 14 章 可迭代的对象、迭代器和生成器

迭代是数据处理的基石。扫描内存中放不下的数据集时,我们要找到一种惰性获取数据项的方式,即按需一次获取一个数据项。这就是迭代器模式(Iterator pattern)。本章说明 Python 语言是如何内置迭代器模式的,这样就避免了自己手动去实现。 在 Python 中,所有集合都可以迭代。在 Python 语言内部,迭代器用于支持: for循环 构建和扩展集合类型 逐行遍历文本文件 列表推导、字典推导和集合推导 元组拆包 调用函数时,使用 * 拆包实参 14.1 Sentence 类第1版:单词序列 序列可以迭代的原因:iter 函数 解释器需要迭代对象 x 时,会自动调用 iter(x)。内置的 iter 函数有以下作用: 检查对象是否实现了 ...

Read more

Fluent Python 笔记 第 13 章 正确重载运算符

运算符重载的作用是让用户定义的对象使用中缀运算符(如 + 和 )或一元运算符(如 - 和 ~)。说得宽泛一些,在 Python 中,函数调用(())、属性访问(.)和元素访问 / 切片 ([])也是运算符,不过本章只讨论一元运算符和中缀运算符。 13.1 运算符重载基础 Python 中的限制: 不能重载内置类型的运算符 不能新建运算符,只能重载现有的 某些运算符不能重载:is、and、or 和 not(不过位运算符 &、 和 ~ 可以) 13.2 一元运算符 要遵守运算符的一个基本规则:始终返回一...

Read more

Fluent Python 笔记 第 9 章 符合 Python 风格的对象

得益于 Python 数据模型,自定义类型的行为可以像内置类型那样自然。实现如此自然的行为,靠的不是继承,而是鸭子类型(duck typing):我们只需按照预定行为实现对象所需的方法即可。 9.1 对象表示形式 实现 __repr__ 和 __str__ 特殊方法,为 repr() 和 str() 提供支持。 9.2 再谈向量类 from array import array import math class Vector2d: typecode = 'd' # typecode 是类属性,在 Vector2d 实例和字节序列之间转换时使用。 def __init__(self, x, y): self.x = float(x) # 把 ...

Read more