流畅的python

第1章 python数据模型

---1.1 一摞Python风格的纸牌

  • 特殊方法,即__method__,又被称为魔术方法(magic method)或者双下方法(dunder-method).

  • 特殊方法的存在是为了被python解释器调用的

  • collections.namedtuple用于构建一个只有少数属性但是没有方法的对象

  • 通过实现__getitem__,可以使对象有[]操作,支持切片操作,可迭代

  • for i in x:实际上是用了iter(x),而这个函数背后则是x.__iter__()方法

  • random.choice可以从一个序列中随机选出一个元素

  • 通过实现一个针对对象的key函数,就可以对该对象进行排序

  • 实现特殊方法来利用python模型的好处是:

    1. 类有统一的标准操作名称

    2. 可以更加方便地利用python的标准库

---1.2 如何使用特殊方法

  • __repr__使对象有一个字符串表示形式.它与__str__的区别是,后者在str()函数或是print()函数被使用.如果一个对象没有__str__函数,python会用__repr__代替.

  • __add__, __sub__, __mul__, __truediv__对应+-*\四种算数运算符

  • 默认情况下,自定义的类的实例总被认为是True,除非对__bool__或__len__有实现.bool(x)会先调用前者,再调用后者,0为False,否则为True.

---1.3 特殊方法一览

第2章 序列构成的数组

---2.1 内置序列类型概览

  • 容器序列可以存放不同类型的数据,存放的是所包含的对象的引用:list,tuple,collections.deque

  • 扁平序列只能容纳一种类型,存放的是值,是一段连续的内存空间:str,bytes,bytearray,memoryview,array.array

  • 可变序列:list,bytearray,array.array,collections.deque,memoryviw

  • 不可变序列:tuple,str,bytes

---2.2 列表推导和生成器表达式

  • 最好只用列表推导来生成列表,而用生成器表达式来初始化元组,数组或其他序列类型.因为生成器表达式可以逐个产出元素,更节省内存.

---2.3 元组不仅仅是不可变的列表

  • 元组除了用作不可变列表,还可以用于没有字段名的记录,其中的每个元素都存放了记录中一个字段的数据和位置

  • 元组拆包(例如平行赋值,函数返回多个值)可应用到任何可迭代对象上,只要被可迭代对象中的元素数量和接受这些元素的元组的空挡数一致.

  • *前缀的变量名可以处理元组拆包中的剩余元素

  • collections.namedtuple可以用来构建一个带字段名的元组和一个有名字的类.

  • 元组支持除了增减元素相关的方法之外的其他所有列表的方法.

---2.4 切片

  • 如果赋值的对象是一个切片,那么赋值语句的右侧必须是个可迭代对象,即使是单个值也要转换成可迭代序列.

---2.5 对序列使用+和*

  • +和*操作不会修改序列,而会新建一个包含同样类型数据的序列作为拼接的结果.

  • 注意:如果a*n中的a是其他可变对象的引用的话,它们会指向同一个可变对象.正确的方式是[[] * m for i in range(n)]

---2.6 序列的增量赋值

  • +=(*=)对应的特殊方法是__iadd__(__imul__),如果没有被实现,解释器会退一步调用__add__.可变序列一般都实现了__iadd__

  • 可变序列的增量赋值会直接追加到原序列上,不可变序列则会创建一个新对象,把原来的元素复制进去后再追加新的元素,因此效率很低.但是str是不可变序列中的一个例外.

  • 下列语句会成功改变t的值,同时抛出异常.因此最好不要把可变对象放在元组里.

t= (1, 2, [3, 4])
t[2] += [5,6]

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

  • list.sort方法会就地排序.因此它返回None,这也是python中函数或者方法对对象进行就地改动时的惯例.

  • sorted可以接受任何可迭代对象作为参数,并新建一个列表作为返回值.

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

  • bisect模块提供了二分查找算法.包含两个主要函数:bisect用于搜索,insort用于插入.

---2.9 当列表不是首选时

  • 如果需要一个只包含数字的列表,那么数组(array.array)比list更高效.创建数组需要一个类型码,表示在底层的C语言应该存放怎样的数据类型.以二进制文件读写数据会显著提高效率.

  • 内存视图(memoryview)能在不复制内容的情况下操作同一个数组的不同切片.

  • 双向队列(collections.deque)是一个线程安全,可以快速从两端添加或者删除元素的数据类型.可以在多线程程序中当作先进先出的栈使用.

第3章 字典和集合

---3.1 泛映射类型

  • 如果一个对象是可散列的,那么在这个对象的生命周期中,它的散列值是不变的,而且这个对象需要实现__hash__和__eq__方法.如果两个可散列对象是相等的,那么它们的散列值一定一样.str,bytes,数值类型,frozenset以及只包含可散列类型的元组都是科三咧类型.

---3.2 字典推导

  • 字典推导类似于列表推导,可以从任何以键值对作为元素的可迭代对象中构建出字典.

---3.3 常见的映射方法

  • 当需要通过查找来插入新值的时候,dict.setdefault比if语句要高效很多.

---3.4 映射到弹性键查询

  • collections.defaultdict为不存在的键提供了一个默认值.

  • 还可以通过继承dict并实现__missing__方法来处理键不存在的情况.

---3.6 子类化UserDict

  • 如果需要创造自定义映射类型,继承UserDict是一个很好的选择.

---3.7 不可变映射类型

  • 如果不能让用户错误地修改某个映射,可以使用types.MappinrgProxyType.将一个字典传给它,它会动态返回原字典的改动,但是不能通过它做任何修改.

---3.8 集合论

  • 集合的本质是许多唯一对象的聚集,可以用于去重.

  • 集合中的元素必须是可散列的,set本身是不可散列的,但是frozenset是可以散列的.

  • 集合包含很多中缀运算符,|取合集,&取交集,-取差集.

  • 同样可以用集合推导式来创建集合

---3.9 dict和set的背后

  • 散列表是一个稀疏数组,python会设法保证大概有1/3的表元是空的.在快要达到阈值的时候,原有的散列表会被复制到一个更大的空间里面.

  • 散列值应该在索引空间中尽量分散,因此越是相似但不相等的对象,它们散列值的差别应该越大.实际运用中,多数搜索过程中并不会有冲突发生.

  • 字典在内存上的开销巨大,因此最好使用元组来存放大量数据.

  • 字典键的次序取决于添加顺序,往里面添加新键可能会改变已有的次序,因此不要对字典同时进行迭代和修改.

  • 上述特点,对集合也几乎都适用.

第4章 文本和字节序列

---4.1 字符问题

  • Unicode中字符的标识(码位)是0~1114111的数字,以4~6个16进制数字表示,而且加前缀"U+".字符的具体表述取决于所用的编码.

---4.2 字节概要

  • python3的bytes或bytearray对象的各个元素是介于0-255之间的整数,但是它们的切片仍是同一类型的二进制序列.

  • 二进制序列可能以ASCII字符本身,转义序列和十六进制转义序列三种形式显示.

---4.3 基本的编解码器

  • python自带超过100种编解码器.

  • UTF编码设计的目的就是处理每一个Unicode码位.

---4.4 了解编码问题

  • 多数非UTF编解码器只能处理Unicode字符的一小部分,此时在编码时会抛出UnicodeEncodeError.

  • 不是每一个字符序列都是有效的UTF编码,如果无法转换时会抛出UnicodeDecodeError.

---4.5 处理文本文件

  • 处理文本的最佳方法是:尽早把输入解码成字符串,尽量晚地把字符串编码成字节序列.python3的open,read和write方法已经帮忙实现了这个原则.

  • 需要在多台设备中或多种场合下运行的代码,打开文件时一定要明确传入encoding,因为不同设备的默认编码可能不同.

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

  • Unicode有组合字符(变音符号和附加到前一个字符上的记号),所以字符串比较起来很复杂.问题点解决方案是使用unicodedata.normaliza进行规范化.一般选取NFC

第5章 一等函数

---5.1 把函数视作对象

  • 在python中,函数是一等对象,函数对象本身是function类的实例.

---5.2 高阶函数

  • 接受函数为参数,或者把函数作为结果返回的函数是高阶函数,例如map,filter.最好使用列表推导或生成器表达式替代它们.

---5.3 匿名函数

  • lambda可以创建匿名函数,一般用于作为参数传给高阶函数.它只是语法糖,实际上也会创建函数对象.

---5.5 用户定义的可调用类型

  • 任何python对象都可以被调用,只要实现了__call__

---5.7 从定位参数到仅限关键字参数

  • 在函数参数中使用*和**可以展开参数并捕获.如果把参数放在前面有*的参数后面,就成为了仅限关键词参数.

---5.10 支持函数式编程的包

  • operator模块为多个算数运算符提供了对应的函数,还有itemgetter和attrgetter可以从序列中取出元素.

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

---6.1 案例分析:重构"策略"模式

  • 策略模式是指:定义一系列算法,把它们一一封装起来,并且使它们可以相互替换.

  • 可以把策略函数作为参数传入对象,简化策略模式.

  • 可以使用globals来获取所有的策略函数,但要求策略函数有一个统一命名规则.

第7章 函数装饰器和闭包

---7.1 装饰器基础知识

  • 装饰器是可调用的对象,其参数是被装饰的函数.装饰器通常把函数替换成另一个函数.

---7.2 Python何时执行装饰器

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

---7.3 使用装饰器改进"策略"模式

  • 在上一章中,如果用promos列表存储策略函数,可能会存在忘记添加的问题.如果使用一个装饰器函数来将策略函数添加到列表中,并将每一个策略函数都用这个装饰器函数来装饰,就可以解决上述问题.

---7.4 变量作用域规则

  • python编译函数的定义体时,会将在函数中赋值的变量判断为局部变量.如果需要让解释器把变量当成全局变量,需要在函数内用global声明.

---7.5 闭包

  • 闭包指延伸了作用域的函数,其中包含函数定义体中引用,但是不在定义体中定义的非全局变量.

  • 未在本地作用域中绑定的变量叫自由变量.

  • 闭包是一种函数,它会保留定义函数时存在的自由变量的绑定,这样调用函数时,虽然定义作用域不可用了,但是仍能使用那些绑定.

---7.6 nonlocal声明

  • 在7.5的例子中,实际上利用了列表是可变的对象.如果想用两个数值count和total来实现,那么在+=时相当于赋值,于是它们会变成局部变量,而不是自由变量.

  • 为了解决这个问题,需要使用nonlocal声明.它的作用是把变量标记为自由变量.

  • 另一种实现方式是,把内部函数需要修改的变量存储伟可变对象的元素或属性,并且把那个对象绑定给一个自由变量.

---7.8 标准库中的装饰器

  • functools.lru_cache可以把耗时的函数的结果保存起来,避免传入相同的参数时重复计算.可以用于优化递归算法.注意lru_cache使用字典存储结果,所以被它装饰的函数的所有参数都必须是可散列的.

  • functools.singledispatch可以把整体方案拆分成多个模块,也就是将普通函数变成泛函数:根据第一个参数的类型,以不同方式执行相同操作.

---7.9 叠放装饰器

  • 把@d1和@d2两个装饰器按顺序应用到f函数上,相当于f=d1(d2(f))

---7.10 参数化装饰器

  • 通过装饰器工厂函数,将真正的装饰器放在内部,就可以接受除了函数以外的参数.

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

---8.1 变量不是盒子

  • 对于面向对象语言中的引用式变量,它们是附加在对象上的标注,而不是盒子.

  • 创建对象之后才会把变量分配给对象.对象在赋值语句右边创建或获取,然后左边的变量才会绑定到对象上.

《流畅的python》读书笔记的更多相关文章

  1. csapp读书笔记-并发编程

    这是基础,理解不能有偏差 如果线程/进程的逻辑控制流在时间上重叠,那么就是并发的.我们可以将并发看成是一种os内核用来运行多个应用程序的实例,但是并发不仅在内核,在应用程序中的角色也很重要. 在应用级 ...

  2. CSAPP 读书笔记 - 2.31练习题

    根据等式(2-14) 假如w = 4 数值范围在-8 ~ 7之间 2^w = 16 x = 5, y = 4的情况下面 x + y = 9 >=2 ^(w-1)  属于第一种情况 sum = x ...

  3. CSAPP读书笔记--第八章 异常控制流

    第八章 异常控制流 2017-11-14 概述 控制转移序列叫做控制流.目前为止,我们学过两种改变控制流的方式: 1)跳转和分支: 2)调用和返回. 但是上面的方法只能控制程序本身,发生以下系统状态的 ...

  4. CSAPP 并发编程读书笔记

    CSAPP 并发编程笔记 并发和并行 并发:Concurrency,只要时间上重叠就算并发,可以是单处理器交替处理 并行:Parallel,属于并发的一种特殊情况(真子集),多核/多 CPU 同时处理 ...

  5. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  6. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  7. 《C#本质论》读书笔记(18)多线程处理

    .NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...

  8. C#温故知新:《C#图解教程》读书笔记系列

    一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...

  9. C#刨根究底:《你必须知道的.NET》读书笔记系列

    一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...

  10. Web高级征程:《大型网站技术架构》读书笔记系列

    一.此书到底何方神圣? <大型网站技术架构:核心原理与案例分析>通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理,并通过一组典型网站技术架构设计 ...

随机推荐

  1. hdu 2795 Billboard 线段树+二分

    Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Probl ...

  2. sudo: unable to resolve host myhostname: Connection timed out

    第一种 原因,/etc/hostname 中的hostname 与/etc/hosts 里面的不对应,导致无法解析 将两个文件的hostname改成一样的即可. /etc/hostname aaa / ...

  3. shell 浮点运算

    浮点运算 let 和 expr 都无法进行浮点运算,但是 bc 和 awk 可以. 范例:求 除以 ,保留 位有效数字 $ echo "scale=3; 1/13" | bc . ...

  4. 内存溢出和内存泄漏 mark下

    https://jingyan.baidu.com/article/495ba841e4423438b30edeb5.html https://www.cnblogs.com/hyh-test/p/8 ...

  5. mysql创建utf8数据库

    1.创建 CREATE DATABASE db_name DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; 2.修改 ALTER DATABASE ...

  6. 解决“centos 下bash: g++: 未找到命令...”

    简单测试一个C++的“Hello World”,发现报错:“bash: g++: 未找到命令...”,因为没有安装编译器G++:然后就百度,出现一大堆的解决办法,什么“sudo apt-get ins ...

  7. Ubuntu 16.04下docker ce的安装

    卸载版本的docker sudo apt-get remove docker docker-engine docker.io 安装可选内核模块 从 Ubuntu 14.04 开始,一部分内核模块移到了 ...

  8. SGE:qsub/qstat/qdel/qhost 任务投递和监控

    参考: Oracle Grid Engine qsub命令 SGE - qsub使用范例 SGE作业基本用法 qsub是最为稳定的底层任务投递系统,就是把一个脚本投递到集群的计算节点上运行. 注意,只 ...

  9. Confluence 6 LDAP 高级设置

    启用嵌套组(Enable Nested Groups) 为嵌套组启用或禁用支持. 一些目录服务器能够允许你在一个组中定义另外一个组.在这种结构下的用户组称为用户组嵌套.嵌套组的配置能够让子用户组继承上 ...

  10. IOS UI-滚动视图(UIScrollView)

    #import "ViewController.h" /* 1.UIScrollView控件是什么? (1)移动设备的屏幕⼤小是极其有限的,因此直接展示在⽤用户眼前的内容也相当有限 ...