Python04-装饰器与迭代器
装饰器
定义:本质是函数,也是使用def关键字定义,(装饰其他函数)为其他函数添加附加功能。
原则:1,不能修改被装饰的函数的源代码。
2,不能修改被装饰的函数的调用方式。
函数即“变量”:定义函数时即是将函数体赋值给了变量名为函数名的变量
高阶函数:单独使用高阶函数也能给原函数添加新功能,只是会改变调用方式,或添加不了新功能;原函数必须在新函数调用时才执行。
嵌套函数
高阶函数+嵌套函数=》装饰器 :使用高阶函数时为了不修改原函数func(源代码), 将原函数func传递进去,然后使用嵌套函数,在内部定义嵌套函数(只是定义,并没有调用执行),外层的高阶函数将嵌套 函数返回。然后在调用高阶函数时,只是会定义内部的嵌套函数,然后将嵌套函数返回传递给原函数变量func,再次调用func(),便是执行了嵌套的函数。嵌套函数内部可
以添加自己的功能。原函数func的参数传递给嵌套函数的形参。若原函数有返回值,则使用装饰器调用后,最终返回的是嵌套函数的返回值。
python解释器回收垃圾(变量,函数),回收的依据是是否还存在引用;引用计数为0时代表对象可以被回收;使用del 删除对象时并没有删除对象本身,只是将引用计数减1了;
定义函数的函数体在内存中是可以看成一堆字符串,定义函数就是将存储这一串字符串的地址赋值函数名这个"变量”(函数即“变量”)。
函数在调用前一定要定义,多个函数的定义顺序是可以打乱的;
生成器
生成器:生成器在调用时才会生成相应的数据。它只能一个一个接着去生成和访问;而且生成器只能记住当前的位置的元素,并不能向前访问数据或是向后跳跃式的访问数据。
python2.X访问生成器的下一个元素的方法是next(), Python3.X是__next__()方法或者next(g), g代表生成器对象
next()取结束时,会报异常,而使用for循环就不会报异常。当然了,发生异常,也是可以捕获的。如下:
while True: try: x = next(g) print('g:', x) except StopIteration as e: print('Generator return value:', e.value) break
当生成器的元素的生成规则很复杂时,可以使用函数,然后在函数内部,使用yied来修饰生成器的元素。函数结束也可以return;如下:
def fib(max): n,a,b = 0,0,1 while n < max: #print(b)
yield b # 使用yield修饰,表示它不再是普通函数,而是生成器,该生成器遇到yield语句便会返回b然后中断,再次遇到next()就会接着上次中断的地方继续执行
a,b = b,a+b # 等价于t=(b,a+b),此时t的元素已经确定,然后a=t[0], b=t[1] n += 1
return ‘done’ # 这里的return语句不再是函数结束的标志,而是生成器内元素取完时,抛出异常返回的信息,表示元素取完。
函数调用时执行,执行结束或者遇到return时就结束;而生成器不同,遇到next(g)时执行,遇到关键字yield语句就返回,再次执行会从yield中断的地方继续执行,上面代码时从小往大的方向,如果从大往小的方向,就适合使用递归。
yield后可为空,然后将yield赋值给变量A,在使用生成器的send(variable)方法传值给yield,并将值赋给A,同时会唤醒yield的中断处,使生成器接着往下执行,知道再次中断或者结束。如下:
import time def consumer(name): print("%s 准备吃包子啦!" %name) while True: baozi = yield print("包子[%s]来了,被[%s]吃了!" %(baozi,name)) def producer(): c = consumer('A') c.__next__() print("老子开始准备做包子啦!") for i in range(10): time.sleep(1) print("做的第%d个包子!"%(i+1)) c.send(i+1) producer()
上面的单线程跑出了多线程的效果,称之为协程
迭代器与可迭代对象
我们已经知道,可以直接作用于for循环的数据类型有以下几种:
1,是集合数据类型,如list、tuple、dict、set、str等;
2,是generator,包括生成器和带yield的generator function。
上面可以直接作用于for循环的对象统称为可迭代对象:Iterable,可以使用isinstance()判断一个对象是否是Iterable对象;
生成器可以作用于for循环,还可以被next()函数返回下一个值,直到最后抛出StopIteration异常表示无法继续返回下一个值;
*可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator,可以使用isinstance()判断一个对象是否是Iterator对象:
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator;把list、dict、str等可迭代对象Iterable变成Iterator可以使用iter()函数,产生一个迭代对象。
使用dir(object),便可以查看对象的所有方法。
这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。
可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性
的,只有在需要返回下一个数据时它才会计算。Iterator甚至可以表示一个无限大的数据流,例如全体自然数,而list是无法存储全体自然数的
在Python3.Xx中,range(10)本身就是一个迭代器,而在Python2.Xx中却不是。
- python的迭代器、生成器、装饰器
- Python迭代器与装饰器
- Python基础知识点——装饰器、生成器、迭代器
- python 学习2:生成器,迭代器,装饰器
- Python之迭代器、生成器、装饰器和递归
- 装饰器、生成器、迭代器、及python中内置函数的使用
- python 学习2:生成器,迭代器,装饰器
- python05 - 迭代器,生成器,装饰器
- Python 04--迭代器、装饰器、软件开发规范
- Python学习笔记-04-迭代器和解析之初见
- python学习笔记四 迭代器,生成器,装饰器(基础篇)
- python︱函数、for、if、_name_、迭代器、防范报错、类定义、装饰器
- Python生成器、迭代器、装饰器
- Python学习(迭代器、生成器、装饰器)
- python学习-Day15-python生成式和生成器、迭代器、装饰器
- 简述python三神器——装饰器、迭代器、生成器
- python迭代器、生成器、装饰器之生成器
- python总结5(迭代器、生成器、装饰器)
- [python自学笔记]生成器、迭代器、装饰器
- 循序渐进Python3(四) -- 装饰器、迭代器和生成器