1.生成器函数,即最终的输出用yield替代return,其他形式不变的函数,而且相比于return,输入yield函数不会立即停止
1 def test(): 2 print('你好') 3 return 10 4 def test_1(): 5 print('你好') 6 yield 10 7 a = test() 8 print(a) 9 b = test_1() 10 print(b) #<generator object test_1 at 0x00000000024F3570> 首次运行时不会执行任何操作,只是变成可迭代对象而已
11 print(b.__next__()) #只有在对其执行next函数操作时才会有打印值 你好 10
2.生成器函数每次执行到yield都会保留函数状态,让函数执行的光标停在当前位置
def test(): yield 1 yield 2 yield 3 a = test() print(a) #<generator object test at 0x00000000024C3138> print(a.__next__()) #1 print(a.__next__()) #2 print(a.__next__()) #3 print(a.__next__()) #直接报错,因为yield后面的输出只能取一次,取完在取则报错
3.相对于return,yield会保留函数当前状态,只有在调用的时候才会执行,而且一次一次的执行,不会因为一次执行全部操作而占据太大的内存导致卡机等(比如下面的代码如果100变成很大很大的数字,第一种执行方法一定会卡)
1 def test(): 2 ret = [] 3 for i in range(100): 4 ret.append('people%s' %i) 5 print(ret) 6 test() #直接打印所有的people 7 def test_1(): 8 for i in range(100): 9 yield i 10 a = test_1() 11 for a1 in a: 12 print(a1) #相比于return一次占据所有打印出people的内存,这种一个个的取显然更省内存
4.列表解析与生成器表达式:下面的代码与上面的代码意义相同,提供了一种简便表示列表的方法与生成器表达式的表示方法
a = ['people%s' %i for i in range(100)]
print(a)
b = ('people%s' %i for i in range(100))
print(list(b))
5.send(a):重要函数,一般与yield一起操作(在yield之后输入),会将a替代yield的返回值被变量接受
def test(): file = yield 0 print(file) yield None a = test() print(a.__next__()) a.send('aini')
6.生产消费者模型:同时运行以下两个函数,相当于只运行一个函数(两个函数互相衔接),比其他方法更省内存(重要)
1 import time 2 def buy(name): 3 print('卖辣条啦!') 4 time.sleep(2) 5 while True: 6 latiao = yield 7 time.sleep(1) 8 print('%s吃了第%s包辣条' %(name,latiao)) 9 10 def sell(): 11 s1 = buy('aaa') 12 s1.__next__() 13 for i in range(1,11): 14 s1.send(i) 15 time.sleep(3) 16 print('诶呀卧槽,aaa撑死啦!') 17 sell()