《流畅的Python》读书笔记二

函数装饰器在导入模块时立即执行,而被装饰的函数只有在明确调用时运行

为了理解 Python 中的赋值语句,应该始终先读右边。对象在右边创建或获取,在此之后左边的变量才会绑定到对象上,这就像为对象贴上标注。不要使用盒子模型了,这个无法解释引用变量赋值。

每个变量都有标识、类型和值。对象一旦创建,它的标识绝不会变;你可以把标识理解为对象在内存中的地址。is 运算符比较两个对象的标识;id() 函数返回对象标识的整数表示。

== 运算符比较两个对象的值(对象中保存的数据),而 is 比较对象的标识。

《流畅的Python》读书笔记二

通常,我们关注的是值,而不是标识,因此 Python 代码中 == 出现的频率比 is 高。

通常使用 None 作为接收可变值的参数的默认值,而不要使用可变类型作为默认值

弱引用不会增加对象的引用数量。引用的目标对象称为所指对象(referent)。弱引用不会妨碍所指对象被当作垃圾回收。弱引用可以用作缓存

改写:两个前导下划线,尾部没有或最多有一个下划线的方式命名实例属性,Python 会把属性名存入实例的__dict__ 属性中,而且会在前面加上一个下划线和类名。可以防止属性被覆盖。

序列可以迭代的原因:iter函数。解释器需要迭代对象 x 时,会自动调用 iter(x)。

迭代器是这样的对象:实现了无参数的 __next__ 方法,返回序列中的下一个元素;如果没有元素了,那么抛出 StopIteration 异常。Python 中的迭代器还实现了 __iter__ 方法,因此迭代器也可以迭代。

可迭代的对象有个 __iter__ 方法,每次都实例化一个新的迭代器;而迭代器要实现 __next__ 方法,返回单个元素,此外还要实现__iter__ 方法,返回迭代器本身。因此,迭代器可以迭代,但是可迭代的对象不是迭代器。

在使用 @contextmanager 装饰的生成器中,yield 语句的作用是把函数的定义体分成两部分:yield 语句前面的所有代码在 with 块开始时(即解释器调用 __enter__ 方法时)执行, yield 语句后面的代码在with 块结束时(即调用 __exit__ 方法时)执行。

在协程中,从根本上把 yield 视作控制流程的方式。协程在 yield 关键字所在的位置暂停执行。前面说过,在赋值语句中,= 右边的代码在赋值之前执行。因此,对于 b = yield a 这行代码来说,等到客户端代码再激活协程时才会设定 b 的值。

yield from 结构会在内部自动捕获StopIteration 异常。这种处理方式与 for 循环处理 StopIteration异常的方式一样:循环机制使用用户易于理解的方式处理异常。对yield from 结构来说,解释器不仅会捕获 StopIteration 异常,还会把 value 属性的值变成 yield from 表达式的值。

相关推荐