python 之 yield表达式

  如果在某个函数中包含了yield, 这意味着这个函数已经是一个Generator, 它的执行 会和其他普通的函数有很多不同。

比如:

  def   h():

    print    ‘To   be  brave‘

    yield   5

  h()

可以看到,调用h()之后,print语句并没有执行, 这就是yield,  那么,如何让print语句执行呢?

  这就是接下来要讨论的问题;

yield 是一个表达式(expression)

  m  =  yield   5

表达式(yield 5)的返回值将赋值给m,所以,认为 m = 5 是错误的。那么如何获取(yield 5)的返回值呢?需要用到后面要介绍的send(msg)方法。

透过next()语句看原理,

  现在,我们来揭晓yield的工作原理。我们知道,我们上面的h()被调用后并没有执行,因为它有yield表达式,因此,我们通过next()语句让它执行。next()语句将恢复Generator执行,并直到下一个yield表达式处。比如:
def h():
    print ‘Wen Chuan‘
    yield 5
    print ‘Fighting!‘

c = h()
c.next()
c.next()调用后,h()开始执行,直到遇到yield 5,因此输出结果:
Wen Chuan
当我们再次调用c.next()时,会继续执行,直到找到下一个yield表达式。由于后面没有yield了,因此会拋出异常:
Wen Chuan
Fighting!
Traceback (most recent call last):
  File "/home/evergreen/Codes/yidld.py", line 11, in <module>
    c.next()
StopIteration

send(msg) 与 next()
了解了next()如何让包含yield的函数执行后,我们再来看另外一个非常重要的函数send(msg)。其实next()和send()在一定意义上作用是相似的,区别是send()可以传递yield表达式的值进去,而next()不能传递特定的值,只能传递None进去。因此,我们可以看做
c.next() 和 c.send(None) 作用是一样的。
来看这个例子:
def h():
    print ‘Wen Chuan‘,
    m = yield 5  # Fighting!
    print m
    d = yield 12
    print ‘We are together!‘

c = h()
c.next()  #相当于c.send(None)
c.send(‘Fighting!‘)  #(yield 5)表达式被赋予了‘Fighting!‘
输出的结果为:
Wen Chuan Fighting!
需要提醒的是,第一次调用时,请使用next()语句或是send(None),不能使用send发送一个非None的值,否则会出错的,因为没有yield语句来接收这个值。

send(msg) 与 next()的返回值
send(msg) 和 next()是有返回值的,它们的返回值很特殊,返回的是下一个yield表达式的参数。比如yield 5,则返回 5 。到这里,是不是明白了一些什么东西?本文第一个例子中,通过for i in alist 遍历 Generator,其实是每次都调用了alist.Next(),而每次alist.Next()的返回值正是yield的参数,即我们开始认为被压进去的东东。我们再延续上面的例子:
def h():
    print ‘Wen Chuan‘,
    m = yield 5  # Fighting!
    print m
    d = yield 12
    print ‘We are together!‘

c = h()
m = c.next()  #m 获取了yield 5 的参数值 5
d = c.send(‘Fighting!‘)  #d 获取了yield 12 的参数值12
print ‘We will never forget the date‘, m, ‘.‘, d
输出结果:
Wen Chuan Fighting!
We will never forget the date 5 . 12
6. throw() 与 close()中断 Generator
中断Generator是一个非常灵活的技巧,可以通过throw抛出一个GeneratorExit异常来终止Generator。Close()方法作用是一样的,其实内部它是调用了throw(GeneratorExit)的。我们看:
def close(self):
    try:
        self.throw(GeneratorExit)
    except (GeneratorExit, StopIteration):
        pass
    else:
        raise RuntimeError("generator ignored GeneratorExit")
# Other exceptions are not caught
因此,当我们调用了close()方法后,再调用next()或是send(msg)的话会抛出一个异常:
Traceback (most recent call last):
  File "/home/evergreen/Codes/yidld.py", line 14, in <module>
    d = c.send(‘Fighting!‘)  #d 获取了yield 12 的参数值12
StopIteration

python 之 yield表达式

时间: 2024-10-12 14:55:28

python 之 yield表达式的相关文章

python之yield表达式

yield表达式用于generator function 调用generator function时,返回一个iterator(函数内语句不被会执行),调用iterator函数时,执行到yield表达式, 当前函数暂停执行,返回表达式的值到调用者,继续调用iterator函数,从暂停处恢复执行.. 遇到yield表达式,与遇到其他表达式差不多,yield表达式也有值,一般为None. 与其他表达式的不同之处在于yield表达式会在yield处返回表达式的值 官方文档描述如下: When a ge

【Python笔记】如何理解python中的generator functions和yield表达式

本篇笔记记录自己对Python的generator functions和yield表达式的理解. 1. Generator Functions Python支持的generator functions语法允许我们定义一个行为与iterator类似的函数,它可以被用在需要循环调用的场合.与普通函数相比,generator functions只是在函数定义中多了1个yield表达式,除此之外,没有其它特别之处. 当generator函数被创建时,python解释器会自动为它实现iteration p

python学习第十节(yield表达式的应用+内置函数)

上节复习 yield表达式g.send(1)send函数是相当于next并且给yield传一个值,先传值,再next 加上装饰器 yield表达式的应用 第一个是当前目录的地址第二个是当前目录下的目录第三个是当前目录下的文件再次next(g)就可以查看当前目录下第一个目录下的信息 ##############下面是更改版本##################### 内置函数all() 所有为true才为trueany() 只要有true 就为truebin()十进制转为2进制oct()十进制转为

yield表达式 python语法

可以先看下这篇文章:http://www.cnblogs.com/jiangtu/articles/6662043.html 原篇是转载的:http://www.python-tab.com/html/2015/pythonhexinbiancheng_0415/946.html  (去掉连字符 - ,博客园显示违禁字..) 之前对 yield表达式 了解的也不清楚,只知道包含 yield表达式 的函数 会被编译成迭代器,如以下代码: def g(n): for i in range(n): y

python中yield用法

在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor). 一.迭代器(iterator) 在Python中,for循环可以用于Python中的任何类型,包括列表.元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器 迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发 StopIteration.任何这类的对象在Python中都可以用for循

python iter yield

>>> lst = range(2)>>> it = iter(lst)>>> it<listiterator object at 0x00BB62F0> 使用迭代器的next()方法可以访问下一个元素:12    >>> it.next()0 如果是Python 2.6+,还有内建函数next(iterator)可以完成这一功能:12 >>> next(it)1 不像一般的函数会生成值后退出,生成器函数

python之yield函数

yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法. 只是粗略的知道yield可以用来为一个函数返回值塞数据,比如下面的例子: def addlist(alist): for i in alist: yield i + 1     取出alist的每一项,然后把i + 1塞进去.然后通过调用取出每一项: alist = [1, 2, 3, 4] for x in addlist(alist): print x,     这的确是yield应用的一个

yield表达式形式

首先了解 1.iterator iterator叫做迭代器,用来遍历可以序列化的数据,比如一个list,set 等,当然如果对象想要能够使用迭代器来遍历,只要在该对象的类中添加__iter__()方法,该方法返回一个迭代器对象,迭代器对象中需要实现next()方法 for example: >>> class sequenceClass(object):   ...     def __init__(self, *args):   ...             self._data =

python中yield使用

16.yield使用 列表推导与生成器表达式 当我们创建了一个列表的时候,就创建了一个可以迭代的对象: >>> squares=[n*n for n in range(3)] >>> for i in squares:     print i 0 1 4 这种创建列表的操作很常见,称为列表推导.但是像列表这样的迭代器,比如str.file等,虽然用起来很方便,但有一点,它们是储存在内存中的,如果值很大,会很麻烦. 而生成器表达式不同,它执行的计算与列表包含相同,但会迭代