关于python:生成器yield关键字详解

49次阅读

共计 2733 个字符,预计需要花费 7 分钟才能阅读完成。

 鉴于 yield 关键字的原理大家了解的都不是很粗浅,明天咱们次要就这一课题进行探讨。

    生成器能够用什么形式失去?

    办法一:

    利用推导式的形式失去生成器

# 列表推导式
list1 = [i for i in range(9)]
print(list1)
# 失去生成器
generator = (i for i in range(9))
print(generator)
执行后果:[0, 1, 2, 3, 4, 5, 6, 7, 8]
<generator object <genexpr> at 0x00000151D63DA830>

    形式二:

    利用函数的形式,用 yield 失去生成器

def generator():
 print('代码开始执行了。。。。。。。。')
 while True:
 response = yield 1
 print('-------------------------------')
 print('response =', response)
g = generator()
print(g)
执行后果:<generator object generator at 0x000001F03B26A830>

    那么咱们当初正式来说说这个 yield 关键字,来解开它的神秘面纱。

    从这个程序中大家看到了什么,是不是咱们的这个执行后果并不是一个 function,而是一个 generator,这个就是咱们的这个 yield 关键字的成果,只有咱们在函数中应用了 yield 关键字,那么它不在是一个函数,而是一个生成器。而且,大家还能够看到,咱们的这个 print 语句并没有执行,大家是否有很多问号?

    那么这个起因还是和它变成了一个生成器的起因所导致的。生成器一样的会和 input 函数一样起一个相似的阻塞作用,须要你调用它外部的 next 办法才会使程序执行一次,当你再一次遇到 yield 的时候,同样又会进行,那咱们来试一下。

def generator():
 print('代码开始执行了。。。。。。。。')
 while True:
 response = yield 1
 print('-------------------------------')
 print('response =', response)
g = generator()
print(g)
print(next(g))
执行后果:<generator object generator at 0x000001F03B26A830>
代码开始执行了。。。。。。。。1

    当初大家看到了什么景象,是不是咱们调用了这个 next 办法之后,代码开始失常执行了,并且给咱们返回出了一个 1,由此能够证实 yield 同样还有一个相似于 return 的性能。然而咱们从这个执行后果来看,是不是发现了 yield 关键字上面的代码没有执行啊?这也就是我说的,遇到了 yield 就会进行的状况。如果咱们当初再去调用一次 next 办法。

def generator():
    print('代码开始执行了。。。。。。。。')
    while True:
        response = yield 1
        print('-------------------------------')
        print('response =', response)
g = generator()
print(g)
print(next(g))
print(next(g))
执行后果:<generator object generator at 0x000001BD4639A830>
代码开始执行了。。。。。。。。1
-------------------------------
response =  None
1

    那么当初大家发现了没有,咱们打印出了三个数据之后又进行了。然而和下面的执行后果比照咱们就不难发现,咱们第二次调用 next 办法的时候,并不是自上往下执行的,而是从上一次进行的地位继续执行的,这也就是咱们的生成器的个性,它会记住你上一次停留的中央,下次持续从这个中央开始执行。

    那好,这是一个景象,大家在看到 response = None 这块,为什么会呈现这么个后果,是不是有同学会纳闷,它的后果不应该是 1 吗?怎么会是 None 呢?这里我要通知大家的是,这个 1 的后果曾经被咱们的 yield 返回进来了,所以这里没有数据,这也是生成器的另一个特色之一,你取出去了这个数据,那么这个数据在生成器外面就不存在了,当你把生成器里的数据取完了,那么它就不可能持续应用了,也就是说生成器只能用一次。

    咱们再来看第三个景象,最初有一个 1 是从哪里输入的?它是下一次循环的 yield 返回进去的,同样到了这里,yield 再次将程序阻塞到了这里,晓得再次调用 next 办法或者 send 办法。

    那么看到这里,是不是又有同学们会纳闷了,老师你说的这个 next 办法我晓得,然而这个 send 办法又是什么货色啊,为什么说 send 也能够调用这个生成器呢?不急,咱们先来写一下这个代码。

def generator():
    print('代码开始执行了。。。。。。。。')
    while True:
        response = yield 1
        print('-------------------------------')
        print('response =', response)
g = generator()
print(g)
print(next(g))
print(next(g))
print(g.send(2))
执行后果:<generator object generator at 0x0000026EE00FA830>
代码开始执行了。。。。。。。。1
-------------------------------
response =  None
1
-------------------------------
response =  2
1

    其实对于咱们这个 send 办法,大家应该不难看到,他就是给咱们的 response 传了一个值而已,那么它为什么同样可能调用出咱们的生成器呢?那是因为 send 同样也是在 Generator 外部的一个办法,它的外面同样封装了 next 办法,所以咱们调用 send 办法同样也是能够调用到生成器的。并且能够给 yield 的赋值对象传递一个值。

    当初大家对于咱们这个 yield 关键字应该有了粗浅的了解了吧?面试官问你,就这么干掉他,你 get 到了吗?

正文完
 0