在理解yaild之前,我们先理解2部分内容
1.生成器是什么?
生成器是迭代器的子集,具有迭代器的所有特征,迭代器可以理解为序列类型数据还存在缓存中的状态
即生成器也可以理解为序列类型数据还存在缓存中的状态
2.不了解yaild前,可以当成return理解
即为函数返回值
现在我们看个例子
def test():
for i in range(2):
yield 4
a = test()
b = list(test())
print(a)
print("##########")
print(b)
>>>><generator object test at 0x0000000001D50DE0>
>>>>##########
>>>>[4, 4]
看到这,你应该明白yield最普通的应用,就是生成一组存在缓存中的数据
我们再看一段代码
def test():
print("start")
while True:
yield 4
print("end")
a = test()
print(next(a))
print("##########")
print(next(a))
>>>>start
>>>>4
>>>>##########
>>>>end
>>>>4
next() 用法为返回迭代器的下一个项目。与迭代器一起使用
这里我们就能看出yield 的独特用法
1.程序开始执行以后,因为test函数中有yield关键字,所以test函数并不会真的执行,而是先得到一个生成器对象(所以不能直接使用数据类型进行接收)
2.函数第一次运行,运行到yield 即停止
3.函数第二次运行,是从上次yield 的地方重新运行,在运行到yield 停止
有些同学可能对遇到即停止,没什么概念,我们再看个例子
def test():
print("start")
while True:
res = yield 4
print("res:",res)
a = test()
print(next(a))
print("##########")
print(next(a))
>>>>start
>>>>4
>>>>##########
>>>>res: None
>>>>4
简单来说就是yield执行完后面代码就立刻停止了,剩下就不会有其他任何操作了,连赋值都没有做
(你也可以理解yield本身的返回值为None,然后赋值为给res)
那遇到这种情况我们也需要返回值怎么办呢?
这就需要send()方法了
a = test()
print(next(a))
print("##########")
print(a.send(5))
>>>>start
>>>>4
>>>>##########
>>>>res: 5
>>>>4
看完上面的例子,就有了个结论
send方法有一个参数,该参数指定的是上一次被挂起的yield语句的返回值。
=====================================================================
说到这里yaild用法大致结束了,剩下就说下,为什么用这个生成器?
1.节约内存,特别对于大量数据来说
#迭代器需要内存少,且一次只生成一个数据
def test(num):
while True:
num=num+1
yield num
for n in test(1000):
print(n)
#一次产生大量数据的列表
for n in range(1000):
print(n)
2.对于多线程运用,特别对于守护进程和安全进程的冲突
(如对于手机,进行密码操作或者人类识别的操作时,为了不冲突卡死,这个是经常配合send使用的)
def task():
print("安全进程开始")
while True:
data = yield #执行完后开启守护进程
print("安全进程开始后:", data)
a = task
a.send(5)
大部分应用是这样,还有其他运用场景用法,可以参照这个大佬链接https://www.zhihu.com/question/345210030/answer/841903171