python-yield详解
2017-04-17 00:49
363 查看
yield详解
1、包含yield的函数
假如你看到某个函数包含了yield,这意味着这个函数已经是一个Generator,它的执行会和其他普通的函数有很多不同。比如下面的简单的函数:
可以看到,调用h()之后,print 语句并没有执行!这就是yield,那么,如何让print 语句执行呢?这就是后面要讨论的问题,通过后面的讨论和学习,就会明白yield的工作原理了。
m = yield 5
表达式(yield 5)的返回值将赋值给m,所以,认为 m = 5 是错误的。那么如何获取(yield 5)的返回值呢?需要用到后面要介绍的send(msg)方法。
4、send(msg) 与 next()
其实next()和send()在一定意义上作用是相似的,区别是send()可以传递yield表达式的值进去,而next()不能传递特定的值,只能传递None进去。因此,我们可以看做
c.next() 和 c.send(None) 作用是一样的。
5. send(msg) 与 next()的返回值
send(msg) 和 next()是有返回值的,它们的返回值很特殊,返回的是下一个yield表达式的参数。比如yield 5,则返回 5 。到这里,是不是明白了一些什么东西?本文第一个例子中,通过for i in alist 遍历 Generator,其实是每次都调用了alist.Next(),而每次alist.Next()的返回值正是yield的参数,即我们开始认为被压进去的东东。我们再延续上面的例子:
《提高你的Python: 解释‘yield’和‘Generators(生成器)’》
https://www.oschina.net/translate/improve-your-python-yield-and-generators-explained
yield就是专门给生成器用的return(加上点小魔法)。
下面是一个简单的生成器函数:
yield执行流程分析
调用get_primes
进入第三行的while循环
停在if条件判断(3是素数)
通过yield将3和执行控制权返回给solve_number_10
接下来,回到insolve_number_10:
for循环得到返回值3
for循环将其赋给next_prime
total加上next_prime
for循环从get_primes请求下一个值
这次,进入get_primes时并没有从开头执行,我们从第5行继续执行,也就是上次离开的地方。
1、包含yield的函数
假如你看到某个函数包含了yield,这意味着这个函数已经是一个Generator,它的执行会和其他普通的函数有很多不同。比如下面的简单的函数:
可以看到,调用h()之后,print 语句并没有执行!这就是yield,那么,如何让print 语句执行呢?这就是后面要讨论的问题,通过后面的讨论和学习,就会明白yield的工作原理了。
In [52]: def h(): ....: print 'To be brave' ....: yield 5 ....: In [53]: h() Out[53]: <generator object h at 0x2a6f370> In [54]: def h(): print 'To be brave' In [55]: In [55]: h() To be brave2、yield是一个表达式
m = yield 5
表达式(yield 5)的返回值将赋值给m,所以,认为 m = 5 是错误的。那么如何获取(yield 5)的返回值呢?需要用到后面要介绍的send(msg)方法。
4、send(msg) 与 next()
其实next()和send()在一定意义上作用是相似的,区别是send()可以传递yield表达式的值进去,而next()不能传递特定的值,只能传递None进去。因此,我们可以看做
c.next() 和 c.send(None) 作用是一样的。
In [78]: def h(): print 'Wen Chuan', m = yield 5 # Fighting! print'm is %s:' % m d = yield 12 print 'We are together!' ....: In [79]: c=h() In [80]: c.next() Wen ChuanOut[80]: 5 In [81]: c.next() m is None: Out[81]: 12 In [82]: c=h() In [83]: c.next() #相当于c.send(None) Wen ChuanOut[83]: 5 In [84]: c.send('fighting') #(yield 5)表达式被赋予了'Fighting!' m is fighting: Out[84]: 12需要提醒的是,第一次调用时,请使用next()语句或是send(None),不能使用send发送一个非None的值,否则会出错的,因为没有yield语句来接收这个值。
5. send(msg) 与 next()的返回值
send(msg) 和 next()是有返回值的,它们的返回值很特殊,返回的是下一个yield表达式的参数。比如yield 5,则返回 5 。到这里,是不是明白了一些什么东西?本文第一个例子中,通过for i in alist 遍历 Generator,其实是每次都调用了alist.Next(),而每次alist.Next()的返回值正是yield的参数,即我们开始认为被压进去的东东。我们再延续上面的例子:
In [91]: def h(): print 'Wen Chuan', m = yield 5 # Fighting! print m d = yield 12 print 'We are together!' ....: In [92]: c=h() In [93]: m=c.next() #m 获取了yield 5 的参数值 5 Wen Chuan In [94]: d=c.send('fighting') #d 获取了yield 12 的参数值12 fighting --- 表达式(yield 12)的值m为fighting In [96]: print 'we will never forget the date',m,'.',d we will never forget the date 5 . 12
《提高你的Python: 解释‘yield’和‘Generators(生成器)’》
https://www.oschina.net/translate/improve-your-python-yield-and-generators-explained
yield就是专门给生成器用的return(加上点小魔法)。
下面是一个简单的生成器函数:
In [3]: def simple_generator_function(): ...: yield 1 ...: yield 2 ...: yield 3 ...: 这里有两个简单的方法来使用它: In [4]: for value in simple_generator_function(): ...: print(value) ...: 1 2 3 In [5]: our_generator = simple_generator_function() In [6]: next(our_generator) Out[6]: 1 In [7]: next(our_generator) Out[7]: 2 In [8]: next(our_generator) Out[8]: 3 In [1]: def is_prime(number): ...: if number > 1: ...: if number == 2: ...: return True ...: if number % 2 == 0: ...: return False ...: for current in range(3, int(math.sqrt(number) + 1), 2): ...: if number % current == 0: ...: return False ...: return True ...: return False ...: In [2]: def get_primes(number): ...: while True: ...: if is_prime(number): ...: yield number ...: number += 1 ...:
yield执行流程分析
调用get_primes
In [30]: def solve_number_10(): ....: # She *is* working on Project Euler #10, I knew it! ....: total = 2 ....: for next_prime in get_primes(3): ....: if next_prime < 2000000: ....: total += next_prime ....: else: ....: print(total) ....: return ....:我们来看一下solve_number_10的for循环中对get_primes的调用,观察一下前几个元素是如何创建的有助于我们的理解。当for循环从get_primes请求第一个值时,我们进入get_primes,这时与进入普通函数没有区别。
进入第三行的while循环
停在if条件判断(3是素数)
通过yield将3和执行控制权返回给solve_number_10
接下来,回到insolve_number_10:
for循环得到返回值3
for循环将其赋给next_prime
total加上next_prime
for循环从get_primes请求下一个值
这次,进入get_primes时并没有从开头执行,我们从第5行继续执行,也就是上次离开的地方。
In [2]: def get_primes(number): ...: while True: ...: if is_prime(number): ...: yield number ...: number += 1 # <<<<<<<<<< ...:最关键的是,number还保持我们上次调用yield时的值(例如3)。记住,yield会将值传给next()的调用方,同时还会保存生成器函数的“状态”。接下来,number加到4,回到while循环的开始处,然后继续增加直到得到下一个素数(5)。我们再一次把number的值通过yield返回给solve_number_10的for循环。这个周期会一直执行,直到for循环结束(得到的素数大于2,000,000)。
相关文章推荐
- Python关键字yield详解以及Iterable 和Iterator区别
- Python yield 详解(二)
- Python 3中的yield from语法详解
- python yield generator 详解
- python yield generator 详解
- python的协程和并发-使用yield实现并有使用详解
- python yield generator 详解
- Python yield语法 使用实战详解
- python中yield函数用法详解
- python yield generator 详解
- Python关键字yield详解以及Iterable 和Iterator区别
- 举例详解Python中yield生成器的用法
- Python中生成器和yield语句的用法详解
- 10 python yield用法详解
- 详解Python3中yield生成器的用法
- Python yield详解
- Python关键字yield详解
- 详解Python中yield生成器的用法
- 详解Python中yield生成器的用法
- python yield generator 详解