一文搞懂Python的yield关键字(新手友好)

在python中,yield是一个不好理解的概念,Up初学Python时看了一些教程,但还是似懂非懂。今天,Up尝试用通俗易懂的语言说清楚yield的用法和原理。

想要更好的理解yield,需要先理解Python的迭代器墙裂建议先看一下Up上一期的文章:一文搞懂Python迭代器

注:

本文长期有效,持续迭代完善,建议收藏。

提前划重点

  • 为什么yield难理解

  • 口诀一:调用时不要看成return

  • 口诀二:next()时看成加强版return

为什么yield难理解

相信很多接触Python的朋友,会觉得yield非常古怪,因为它看上去和return很相似,但却完全不是一会儿事儿。

这是我们熟悉的代码:

def func_return():
    value = 1
    return value # 到这里函数就结束了,返回value这个值
	print(value) # 无效代码 return之后代码都不会被运行

而yield却很奇怪:

def func_yield():
    yield 1  # 第一次返回1 并停住
    yield 2  # 第二次返回2 并停住
    yield 3  # 第三次返回3 并停住

我们查阅资料会发现,yield下面还可以用yield?居然还可以停住?下一次再从上次停的地方接着执行?怎么做到的?

是不是觉得特别高级,理解起来也不容易。Up编了两个口诀,相信大家记住这两个口诀就不会觉得难理解了。

口诀一:调用时不要看成return

回到上面的例子,当我们调用func_return(),它会返回return后面的value。这个是我们非常熟悉的。

value_return = func_return()
print(value_return) # 打印 1

但是对于func_yield,当我们调用它的时候,它返回的值和yield后面的值无关,它会返回一个生成器对象。

value_yield = func_yield()
print(type(value_yield)) # 打印value_yield的类型,

你可以理解成,当你调用func_yield时,python解释器发现他是一个包含yield的函数,于是并不会直接执行函数,而是自动生成一个这个函数专属的生成器对象,并返回这个生成器对象。

生成器是一种特殊的迭代器,所以它本质就是一个迭代器。对于迭代器不太了解的朋友,可以先看一下Up最开始提到的文章。

所以,我们第一个口诀就是,调用时不要把yield看成return。它返回的是一个生成器对象,和yield后面是什么完全无关!

口诀二:next()调用时看成加强版return

继续上面的例子,我们得到了一个生成器对象。那该怎么用它呢?

如果你对迭代器熟悉的话就会知道,迭代器可以由next()函数触发,用于从迭代器中返回下一个值。

具体来说

  • 从上次暂停的位置(首次的话就是从函数开头)继续往下执行,并找到第一个遇到的yield,返回yield后面的值,停住不再继续执行。(如果找不到报错StopIteration)
  • 把当前执行到的位置,局部变量等信息,保存到生成器对象里。这样下次调用next()就可以把当前的位置、状态恢复出来,接上继续执行。
next(value_yield)  # 返回1
next(value_yield)  # 返回2
next(value_yield)  # 返回3
next(value_yield)  # 报错StopIteration

所以next()调用时,yield它确实和return一样返回了值。但它还做了一些保存状态的工作,你可以把它看成是一个加强版的return

现在看起来,yield是不是也没有那么难理解。大家可以记住这两个口诀,相信yield的使用就没问题了。

下期预告

下期我们也尽可能通俗易懂拆解一下python的装饰器。听说点赞越多,Up更得越快。感谢支持,下期见!

你可能感兴趣的:(python,python,开发语言)