总之就是黑人问号.gif。
跟着廖大神学python就是等到实战部分的时候就发现自己啥也没搞清楚,实战第三天,我已经黑了两天。
文章目录
关于yield和async/await的几个特别好的参考:
python中yield的用法详解——最简单,最清晰的解释
async/await入门指南
1、前言
Python教程实战第三天的部分,编写ORM,本来觉得对于生成器和异步IO的理解还挺清楚的,结果等写不下去只能抄代码的时候发现各种yield和yield from还有async/await交替使用的时候果然就一脸懵了(哼!幼齿的感觉真好!)总之,看了一会之后我的内心的疑惑已经简化成了“咦,yield跟from为啥要放到一起丫,为啥这个函数里的for循环前面也要用async……”这样的循环bgm
哦,然后就是从头开始撸。yield它爸是生成器,yield from它爸是……啥?
2、生成器——yield其实是个传送门
关键字不是用来定义一种规则的么。yield关键字定义了一种函数执行的规则,和return不一样的规则,所以使用yield的函数就叫做不一样函数(啥,是生成器啊啊啊)。
第一次见到yield就是在生成器里。
复习一下生成器的两种创建方法:
- 将一个列表生成式的
[]
改成()
L = [x * x for x in range(10)] # 列表
g = (x * x for x in range(10)) # 生成器
- 包含yield关键字:其实应该说是用yield来返回生成结果
# 斐波拉契数列生成器
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
2.1、使用yield传送输出值
使用yield的函数,执行流程就和普通函数不一样了:
普通函数:遇到return
或者最后一行函数语句就返回。
generator:每次调用next()
执行,遇到yield
语句返回,再次执行时从上次返回的yield语句处继续执行。
不一样函数生成器和一般函数不一样的地方在于(它很特别):
- 特别的关键字yield:使用yield传送输出值
- 特别的打开方式next()方法:直接调用函数并不会执行,需要调用next方法来执行
- 特别懒:调用一次执行一次规则计算(看到yield就不干活了,把值给调用方一丢——交作业,瘫着爱咋咋)
不过生成器不就是用来节省空间的么,本来就是打算让它边循环边计算的(基因懒,很优秀)。
def odd():
print('step 1')
yield 1
print('step 2')
yield(3)
print('step 3')
yield(5)
return 'Done'
o = odd()
print(next(o))
print(next(o))
print(next(o))
print(next(o))
输出:
不知道为啥看这一类包含多个yield的函数的时候会觉得恶意满满,前面还觉得yield是只是放学铃,这一看,yield还是下课铃,一出现就可以休息(学生狗真幸福!)
当然,如果游戏已经结束了(return了或者没有可执行的代码)却一直不给下课铃(上面例子种最后一个next()
调用,generator会继续执行但后面再没有yield),就有人报警了(StopIteration),然后报警完了还会带出游戏结束时的返回值(return 'Done'
)?
补充一下要通过正规途径获取游戏结束的返回值,就是自己多看着点小调皮们,逮住那个翻墙出去告状的小可怜:
(以下是坏坏的班主任上线的代码)
def odd():
print('step 1')
yield 1
print('step 2')
yield 3
print('step 3')
yield 5
return 'Done'
o = odd()
while True:
try:
print(next(o))
except StopIteration as e:
print('return %s' % e.value)
break;
输出:
2.2、使用yield辅助定点投放输入值
虽然掌握了计算方法,但是只是闷头自习可是没办法与时俱进的(bgm~红极一时?的大武汉口号。快感受下那个一身正气的感叹号)