迭代器
- 是访问集合元素的一种方式
- 迭代器对象从第一个元素开始访问,直到所有的元素被访问完结束;只能往前不会后退(迭代器是一个可以记住遍历的位置的对象)
- 有两个方法:iter() (创建迭代器对象); next() (输出迭代器的下一个元素)
- 创建方式:把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() ;此外,字符串,列表或元组对象也都可用于创建迭代器:
- __iter__() 方法返回一个迭代器对象(返回迭代器自身);
- __next__() 方法返回下一个迭代器对象(返回容器中的下一个值)。(StopIteration 异常用于标识迭代的完成,在 __next__() 方法中可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代,从而防止出现无限循环的情况) (也可以使用for循环进行迭代)
生成器
- 使用yield的函数(一种创建generator的方式)(yield用以支持迭代器协议)
- 是一个返回迭代器的函数 (调用生成器函数,返回的是迭代器对象);
- 遇到 yield 时函数暂停并保存当前的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
- “Python’s generators proivde a convenient way to implement the iterator protocol", 完全可以像使用iterator一样使用generator,定义iterator需要分别实现__iter__()和__next__()方法,定义generator()只需要yield
- 另一种创建generator的方法:把一个列表生成式的
[]
改成()
装饰器
- 是修改其他函数功能的函数(或类),可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,装饰器的返回值也是一个函数/类对象
- 适合有切面需求的场景,如权限校验、性能测试、日志记录等;可以使得我们抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用
- 构建装饰器类:使用类装饰器主要依靠类的__call__方法
面向切面编程
把重复使用的代码片段称为切面,把这些代码片段切入的目标称为切入点。面向切面编程就是把所有可能重复的代码、固定流程的代码分离出来做成切面,在需要时切入到目标类或者目标函数中。(比如针对timeit函数这个装饰器,一个函数开始处开始计时和退出时需要计时,这被称为一个横切面)
代理模式
- 属于结构型模式(另外两种是创建型和行为型)
- 在直接访问对象时带来的问题(比如对象创建开销很大或者某些操作需要安全控制问)或者想在访问一个类时做一些控制,因此我们可以在访问此对象时加上一个对此象的访问层(作为中间层)
Notes
闭包:
在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数就被认为是闭包。
并发:
- yield:把运行中的函数进行了一个保存退出(也就是中断)。然后把线程的的控制权从函数手里交换到我们手里, 我们可以在适当的时机再继续运行该函数
- yield与return区别:return一旦返回,则代码段执行结束,但是yield在返回值以后,会交出CUP的使用权,代码段并没有直接结束,而是在此处中断,当调用send()或者next()方法之后,yield可以从之前中断的地方继续执行
- send()方法:允许我们向生成器中传值,调用send()后程序被唤醒,将send的值传递给yield之前的变量,程序继续运行,直到遇到yield将新的返回值返回,程序再次中断。如此继续下去,直到程序结束
- send(None)等效于next(),用以启动生成器
- yield from:用以简化嵌套调用生成器的语法复杂度;yield from 后面需要加可迭代对象,可以是普通的可迭代对象,也可以是迭代器、生成器。(它可以把可迭代对象里的每个元素一个一个的yield出来)
- 包含yield from表达式的生成器函数被叫做
委托生成器,
yield from后面的生成器函数是子生成器
。委托生成器的作用是:在调用方与子生成器之间建立一个双向通
道
- 包含yield from表达式的生成器函数被叫做
- async / await:
async/await的出现是为了协程,是为了区分生成器使编程更加明确,来提升Python中的异步编程体验。
await比yield from的抽象层高一丢, 更强调的是“等”这个操作。yield from后面的对象是一个Iterable,await后面是一个Awaitable(一个类实现了__await__方法,它构造的对象就是一个Awaitable)。在协程函数中,可以通过await来挂起自身的协程。@asyncio.coroutine
替换为async
yield from
替换为await