1.迭代器(Iterator)
迭代器是访问集合元素的一种方式。有下面特点:
1)每次调用__next__()方法只访问一个元素,而且不能后退,便于循环比较大的数据集合,节省内存;(当容器中没有可访问的元素后,next()方法将会抛出一个StopIteration异常终止迭代器)
2)只能从头到尾访问,不能随机访问某个值;
3)迭代器提供了一个统一的访问集合的接口,只要定义了iter()方法对象,就可以使用迭代器访问。
迭代器使用:
lis=['a','b','c','d'] a=iter(lis) print(a.__next__()) print(a.__next__()) print(a.__next__()) print(a.__next__()) print(a.__next__()) #没有元素获取,导致StopIteration报错 #运行结果 a b c d Traceback (most recent call last): File "F:/Python/pythoncode/s12/study/study5.py", line 318, in <module> print(a.__next__()) StopIteration
使用for循环访问迭代器:
lis=['a','b','c','d'] a=iter(lis) for st in a: print(st) #运行结果 a b c d
2.生成器(Generator)
一个调用返回迭代器的函数,就叫做生成器。函数中包含yield语法,这个函数就会变成生成器。
1)生成器表达式
用来生成有规律的生成器
格式:generator_name=('生成规则’ for i range(num) if 'i的条件‘)
1 a=('a' for i in range(5) if i%2) 2 b=(i+1 for i in range(5)) 3 print(a,type(a)) 4 print(b,type(b)) 5 print(b.__next__()) 6 print(b.__next__()) 7 print(b.__next__()) 8 print(b.__next__()) 9 print(b.__next__()) 10 11 #运行结果 12 <generator object <genexpr> at 0x00F9CAE0> <class 'generator'> 13 <generator object <genexpr> at 0x00F9CC90> <class 'generator'> 14 1 15 2 16 3 17 4 18 5
2)yield创建生成器
def fun_ex(a): yield 1 re=fun_ex(2) print(re.__next__(),type(re)) #运行结果 1 <class 'generator'>
3)生成器实现单线程的异步并发效果
def gen_ex(a): while a>0: a-=1 yield 1 print('hello') re=gen_ex(2) print(re.__next__()) print('中断打印') print(re.__next__()) #运行结果 1 中断打印 hello 1
生成器是每次调用返回一次数据,所以可以在中途插入其他操作,形成一种异步效果,如例子中先来个“中断打印”
4)生成器中的send()方法使用
def gen_ex(a): while a>0: a-=1 b=yield print(b) re=gen_ex(5) re.__next__() re.send(5) print('中断打印') re.send(6) #运行结果 5 中断打印 6
send()可以给yield传参数,yield作为接收。这里yield的运行情况和return在函数上起的作用有些区别。
如生成器使用一个__next__()方法,它会运行到yield这行,而停止。但是再使用send()方法,函数直接从yield这行开始运行,并赋值给b,然后运行下去循环一次到yield这行停止。
3.装饰器
装饰器的作用在于,对已有函数,在不改变它内在封装上扩展它的功能。如:
def start(func): def inner(arg): print('how are you!') func(arg) return inner @start def user(arg): print('hello %s'%arg) # user=start(user) #这条功能和@start一样 user('olive') #运行结果 how are you! hello olive
上例中,start就是实现装饰器功能,@start和user=start(user)一样的功能效果,@start更具有装饰器特征。
上面是传单参数装饰器,也可以多参数或n参数,如:
1 def start(func): 2 def inner(*args,**kwargs): 3 print('how are you!') 4 func(*args,**kwargs) 5 return inner 6 7 @start 8 def user(*args,**kwargs): 9 print('hello ' ) 10 11 user('olive','a','b') 12 13 #运行结果 14 how are you! 15 hello
装饰器可以写一个装饰器框架,把装饰器当函数调用。