Generator (Generator)
What is Builder
Builder is a special kind of iterators, generators realized迭代器协议__iter__(),__next__()
Builder solve any problems
If there is one million data should we deal with, we accessed by way of the list, then the million data is stored in memory, so that will be very memory consuming, but if we use the generator, then, whenever dealing with a when data in memory is only the equivalent of a saved data, it saves a lot of memory
Simple Case
When generating object __next__()
when the generator function is executed next to the yield, and returns a parameter
Example One
def zx():
yield 1
print(1)
if __name__ == '__main__':
zx=zx()
data=zx.__next__()
print(data)
1
Example Two
Trigger the exception of two ways StopIteration
1. After completion of the last element iteration, triggering abnormal StopIteration
def zx():
yield 1
print(1)
if __name__ == '__main__':
zx=zx()
data=zx.__next__()
data=zx.__next__()
1
Traceback (most recent call last):
File "C:/Users/Administrator/Desktop/01python/研究/生成器/t1.py", line 8, in <module>
data=zx.__next__()
StopIteration
2. Run the generator function when it came to return, the return value will be described abnormal value, as in the example 2
def zx():
yield 1
return 2
print(1)
yield 3
if __name__ == '__main__':
zx=zx()
data=zx.__next__()
data=zx.__next__()
Traceback (most recent call last):
File "C:/Users/Administrator/Desktop/01python/研究/生成器/t1.py", line 10, in <module>
data=zx.__next__()
StopIteration: 2
Iterator object and produce difference generator
Iterator object is achieved by an iterative object can be __iter__()
generated
zx=[1,2,3,4,5,6,7,8,9]
z1=zx.__iter__()
Create a pattern generator in a similar manner to generate the object
def zx():
for i in range(10):
yield i
z1=zx()
send method
Implemented mainly by the generator coroutine send method
Example 1 - misuse
def dog():
print('小乌')
while True:
food = yield
if food == '骨头':
yield '好吃'
else:
yield '旺旺旺'
xw = dog() #只是用于返回一个生成器对象,函数并不会执行下去
print(xw.send('骨头'))
Error, can not send non-null value to the generator just created
Traceback (most recent call last):
File "C:/Users/Administrator/Desktop/01python/研究/生成器/t5_send.py", line 10, in <module>
print(xw.send('骨头'))
TypeError: can't send non-None value to a just-started generator
Error message saying can not send a non-null value, then we'll try to send a None what happens
print(xw.send(None))
The successful implementation of the
小乌
None
In fact, you can also use __next__()
can do this print results
print(xw.__next__())
Same results
小乌
None
in conclusion
1. The __next__()
effect of fact and send (None) as
2.yield default return None
Example 2 - Use the proper
def dog():
print('小乌')
while True:
food = yield
if food == '骨头':
yield '好吃'
else:
yield '旺旺旺'
xw = dog() #只是用于返回一个生成器对象,函数并不会执行下去
print(xw.__next__())
print(xw.send('骨头'))
result
小乌
None
好吃
in conclusion
1. When the generator has just been created, or the first time to next send (None), can not directly send (non-null parameter)
2.send () function assigned to a yield of
to sum up
1. The __next__()
effect of fact and send (None) as
2. When the generator has just been created, for the first time before next use or send (None), can not directly send (non-null parameter)
3.send () method is equivalent to the __next__()
binding of functions and assignment
Generator implements counter and coroutine
counter
def jishu():
i = 0
while True:
zx = yield i
if zx == "按一下":
i+=1
elif zx == "重置":
i=0
js=jishu()
print(js.__next__())
print(js.send("按一下"))
print(js.send("按一下"))
print(js.send("按一下"))
print(js.send("按一下"))
print(js.send("重置"))
print(js.send("按一下"))
print(js.send("按一下"))
0 初始化
1 按一下
2
3
4
0 重置
1
2
Coroutine
Bun
def consumer(name):
print(f"{name}老板上包子")
while True:
baozi = yield
print(f"{name}:吃了{baozi}")
def producer():
for i in range(2):
print('厨师做了两个包子')
c1.send(f"肉包{i}")
c2.send(f"菜包{i}")
c1 = consumer("小黄")
c2 = consumer("小乌")
c1.__next__()
c2.__next__()
producer()
小黄老板上包子
小乌老板上包子
厨师做了两个包子
小黄:吃了肉包0
小乌:吃了菜包0
厨师做了两个包子
小黄:吃了肉包1
小乌:吃了菜包1