python三器:装饰器、迭代器、生成器

装饰器
前戏:闭包
在函数内定义函数,并且内函数引用了外函数的局部变量。
装饰器原则(适用场合):不修改被修饰函数的调用方式及源码
扩展知识:python变量查找顺序
LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
locals 是函数内的名字空间,包括局部变量和形参
enclosing 外部嵌套函数的名字空间(闭包中常见)
globals 全局变量,函数定义所在模块的名字空间
builtins 内置模块的名字空间
注意的是:在全局无法查看局部的,在局部可以查看全局的
装饰器的使用
1)装饰器原则:不修改被修饰函数的调用方式及源码
2 )注意。装饰器,装饰器被装饰后,函数指向装饰器函数内部的闭包,
  这里有个陷阱,介于装饰器函数和闭包之间的作用域语句执行一次之后便不会再执行,所以判断语句要放在闭包之中
3 )知道带参数的装饰器为什么要双重闭包了,因为装饰器函数一定要有一个func参数,但是带参数函数已经带了其他参数了,所以只能在内部再定义一个带func的函数
4 ) 在闭包中,介于外层函数和闭包函数中间的那一层中的变量,可以在闭包作用域中引用,但是就是不能判断重新赋值
 (即判断语句中有这个变量,判断执行语句中也有这个变量),因为LEGB作用域查找,重新定义局部变量会覆盖中间层的同名变量,引发UnboundlocalError



迭代器
什么叫迭代?

每次迭代都是依赖上次结果而来的
迭代流程是怎样的?
当任何可迭代对象传入到for循环或其他迭代工具中进行遍历时,迭代工具都是先通过iter函数获得与可迭代对象对应的迭代器,然后再对迭代器调用next函数,
不断的依次获取元素,并在捕捉到StopIteration异常时确定完成迭代。
什么是可迭代对象?什么是迭代器对象?两者有什么区别?

可迭代对象指的是内置有__iter__方法的对象,该方法可以返回出迭代器对象
迭代器对象指的是即内置有__iter__又内置有__next__方法的对象,即直接实现了实现了迭代器协议的对象(可以传入next函数)
为什么要有迭代器?
对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。
但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,
则必须找出一种不依赖于索引的迭代方式,这就是迭代器

迭代器优缺点
优点:
提供一种统一的、不依赖于索引的迭代方式
惰性计算,节省内存,迭代器是一点一点读取数据,而不是一次性加载所有数据到内存
缺点:
无法获取长度(只有在next完毕才知道到底有几个值)
并且只能前进不能后退

生成器

1 )生成器是迭代器的一种,表现在函数内部有yield关键字,yield对比return,可以返回多次值,可以挂起/保存函数的运行状态
2)生成器使用send的时候,yield为赋值表达式形态,可以通过yield的返回值获取send传入的参数
  注意的是:g.send(None) #对于表达式形式的yield,在使用时,第一次必须传send(None)用作初始化,或者先调用next(g),
  如果真的要使用send这种模式,可以写一个装饰器函数初始化
注意的是:由于生成器有惰性计算,如果和文件读写操作绑定一起会报错,因为到你需要的生成器的值时,文件已经被关闭了

猜你喜欢

转载自www.cnblogs.com/ziyide/p/9100482.html