def g_01():
print('---g_01-01---') #代码执行位置标记
point_01=yield
print('---g_01-02---')
for _ in range(5):
print('---g_01---:{}'.format(point_01))
def main_01():
g=g_01()
print('---main_01-01---') #代码执行位置标记
g.send(None) #我们的核心:预激生成器
print('---main_01-02---')
g.send('Android')
'''
执行:
main_01()
输出结果:
---main_01-01---
---g_01-01--- 我们执行完成预先预激生成器后,生成器g_01执行到 ---g_01-01---位置
---main_01-02--- 从生成器返回调用函数 main_01
---g_01-02--- 通过调用者main_01,我们send('android'),向生成器传送一个值,生成器接受这个值,并向下执行
---g_01---:Android 执行生成器代码
---g_01---:Android 执行生成器代码
---g_01---:Android 执行生成器代码
---g_01---:Android 执行生成器代码
---g_01---:Android 执行生成器代码
StopIteration 生成器代码执行完毕,出发StopIteration异常,抛给send方法的调用者main_01函数
'''
'''
所以,我们不能在预激线程的代码中传入数据,应为那时生成器的代码还没执行到yield的位置,只有预激生成器,
让生成器执行到yield前停住。往后我们调用send传入数据,此时生成器才能接受我们传入的值
下面我们验证下
'''
def main_02():
g=g_01()
print('---main_01-01---') #代码执行位置标记
# g.send(None) #我们的核心:预激生成器
print('---main_01-02---')
g.send('Android')
'''
执行:
main_02()
输出结果:
---main_01-01---
---main_01-02--- #我们取消了传送send(None),生成器开始到第一个yield之间的代码没有执行
Traceback (most recent call last):
File "/home/qing/PythonWebApp/02_异步IO/02_asyncio案例/关于预激线程的探讨.py", line 48, in <module>
main_02()
File "/home/qing/PythonWebApp/02_异步IO/02_asyncio案例/关于预激线程的探讨.py", line 42, in main_02
g.send('Android')
TypeError: can't send non-None value to a just-started generator
所以,我们预激生成器的意义是将代码生成器代码在神奇的yield位置停住,这个生成器创建代码并不会将代码执行到yield位置),生成器准备接受参数
'''
'''
或许大家会对生成器到底是在yield的前面停住,还是在yield执行过程中停住这个问题有疑问,
下面我们来看下这两个例子,来看下生成器是如何执行yield的
'''
def gen_01():
print('gen_01--before y1--')
y1=yield 'yield_y1'
print('gen_01--after y1:{}--'.format(y1))
print('gen_01--before y2--')
y2=yield 'yield_y2'
print('gen_01--after y2:{}--'.format(y2))
print('gen_01--before y3--')
y3=yield 'yield_y3'
print('gen_01--after y3:{}--'.format(y3))
return 'jet'
def main_01():
g=gen_01()
print('main_01--before s1--')
s1=g.send(None)
print('main_01--after s1:{}--'.format(s1))
print('main_01--before s2--')
s2=g.send('send_s2')
print('main_01--after s2:{}--'.format(s2))
print('mian_01--before s3--')
s3=g.send('send_s3')
print('main_03--after s3:{}--'.format(s3))
print('main_01--before s4--')
s4=None
try:
s4=g.send('s4')
print('main_01--stop iteration:{}--'.format(s4))
except StopIteration as e:
print('main_01--Exception_StopIteration:{} --'.format(e))
'''
执行:
main_01()
输出结果:
main_01--before s1--
gen_01--before y1--
我们在调用者main中调用send预激生成器,然后程序跳到生成器中执行,
生成器件执行到第一个yiled出停住,第一个yield右边的值返回给调用者main,程序跳回main执行
main_01--after s1:yield_y1--
main_01--before s2--
调用者main接受生成器yield过来的参数,继续往下执行,直达执行到第二个send,程序跳转到生成器中执行
gen_01--after y1:send_s2--
gen_01--before y2--
生成器从第一个卡住的yield位置向下执行,接收调用者main函数send过来的参数,然后继续往下执行,直到遇到二个yield,将第二个yield右边的值返回给调用者main,程序跳回main执行
main_01--after s2:yield_y2--
mian_01--before s3--
调用者main接受生成器yield过来的参数,继续向下执行,直到执行到第三个send,程序跳转到生成器中执行
gen_01--after y2:send_s3--
gen_01--before y3--
生成器从第二个卡住的yield位置向下执行,接受调用者main函数send过来的参数,然后继续向下执行,直到遇到第三个yield,将第三个yield右边的值返回给调用者main,程序跳回main执行
main_03--after s3:yield_y3--
main_01--before s4--
调用者main接受生成器yield过来的参数,继续向下执行,直到执行到第四个send,程序跳转到生成器中执行
gen_01--after y3:s4--
生成器从第三个卡住的yield位置向下执行,接受调用者main函数send过来的参数,然后继续向下执行,直达全部执行完毕(return 'jet'),
然后向上抛出StopIteration(这个异常的__str__返回'jet'的__str__,如果没有返回值,这个异常的__str__返回""),调用者main充当StopIteration的接盘侠
main_01--Exception_StopIteration:jet --
调用者main函数,捕获异常并执行接下来的代码,直到执行完毕
'''
def gen_02():
print('gen_02--before y1--')
y1=yield 'yield_y1'
print('gen_02--after y1:{}--'.format(y1))
print('gen_02--before y2--')
y2=yield 'yield_y2'
print('gen_02--after y2:{}--'.format(y2))
print('gen_02--before y3--')
y3=yield 'yield_y3'
print('gen_02--after y3:{}--'.format(y3))
def main_02():
g=gen_02()
print('main_02--before s1--')
s1=g.send(None)
print('main_02--after s1:{}--'.format(s1))
print('main_02--before s2--')
s2=g.send('send_s2')
print('main_02--after s2:{}--'.format(s2))
print('mian_02--before s3--')
s3=g.send('send_s3')
print('main_02--after s3:{}--'.format(s3))
print('main_02--before s4--')
s4=None
try:
s4=g.send('s4')
print('main_02--stop iteration:{}--'.format(s4))
except StopIteration as e:
print('main_02--Exception_StopIteration:{} --'.format(e))
'''
执行:
main_02()
输出:
main_02--before s1--
gen_02--before y1--
main_02--after s1:yield_y1--
main_02--before s2--
gen_02--after y1:send_s2--
gen_02--before y2--
main_02--after s2:yield_y2--
mian_02--before s3--
gen_02--after y2:send_s3--
gen_02--before y3--
main_02--after s3:yield_y3--
main_02--before s4--
gen_02--after y3:s4--
生成器从第三个卡住的yield位置向下执行,接受调用者main函数send过来的参数,然后继续向下执行,直达全部执行完毕,
然后向上抛出StopIteration(这个生成器没有return返回值,则异常的__str__返回“”),调用者main充当StopIteration的接盘侠
main_02--Exception_StopIteration: --
调用者main函数,捕获异常并执行接下来的所有代码
'''
'''
写在最后:
调用者调用生成器的send,
如果是第一次调用
会从生成器代码的开始一直运行到遇到的第一个yield,并将yield右边的值返回给调用者,停在yield,程序执行由生成器代码切换到调用者代码
如果是普通情况下的调用
会跳掉生成器代码执行,生成器从当前卡住的yield开始将接受send的参数,并继续往下执行,直到遇到下一个yield (yield_02),
并将这个yield (yield_02)的右边的值返回给调用者,生成器件停在yield (yield_02),程序跳动回调用者执行
如果是最后一次调用
也就是及接下来没有代码或者剩下的所有代码中没有yield(全部执行完也不会遇到yield),执行完后直接向调用者抛出StopIteration(如果生成器最有有return XX,则我们将XX包在StopIteration对象中返回给调用者)
'''
网友评论