Keywords: yield
andsend
def simple_coroutine(a): print('-> start') b = yield a print('-> recived', a, b) c = yield a + b print('-> recived', a, b, c)# runcsc = simple_coroutine(5)aa = next(sc) # 预激print(aa)bb = sc.send(6) # 5, 6print(bb)cc = sc.send(7) # 5, 6, 7print(cc)
-Start
5
-Recived 5 6
11
-Recived 5 6 7
Analysis: Moving the brain
Delegation Builder: Generator function containing yield from
from collections import Namedtupleresclass = Namedtuple (' Res ', ' Count Average ') # sub-generator def Averager (): total = 0.0 Count = 0 average = none and True:term = yield if term is None: Break Total + = Term count + = 1 average = Total/count return Resclass (count, average) # delegate build Device def grouper (storages, key): While True: # gets Averager () return value storages[key] = yield from Averager () # client code D EF Client (): Process_data = {' boys_2 ': [39.0, 40.8, 43.2, 40.8, 43.1, 38.6, 41.4, 40.6, 36.3], ' boys_1 ': [1.38, 1.5, 1.32, 1.25, 1.37, 1.48, 1.25, 1.49, 1.46]} storages = {} for K, V in Process_data.items (): # get co-coroutine = Grouper (storages, K) # Pre-excitation co-process Next (coroutine) # sends data to the coprocessor for DT in v:coroutine.send (DT) # to terminate the coprocessor Coroutine.send (None) print (storages) # runclient ()
{' Boys_2 ': Res (count=9, average=40.422222222222224), ' Boys_1 ': Res (count=9, average=1.3888888888888888)}
Explain:
client()
function starts, for K, v Loop, each time a new grouper instance is created Coroutine
next(coroutine)
Pre-excitation process, enter while True loop, call averager()
, yield from at place pause
- The
for dt in v
grouper instance is still paused after the inner layer finishes, so the assignment for Storages[key] is not completed
coroutine.send(None)
, the term becomes the None,averager child generator aborts, throws Stopiteration, and contains the returned data in the exception object's value, the yield from directly fetching the stopitration, assigning the value of the exception object to the Storages[key]