前段时间在读trac 中wiki模块的源码的时候,发现了很多地方都使用了yiled这一关键词,

感觉是在需要返回某个值的地方通过yield来代替return,

不是很明白其用法,所以仔细研究下。

一个使用了yiled关键字的函数就不再是一个普通的函数了,而是一个生成器函数(generator function),

当函数被调用的时候将返回一个迭代器(iterator)。

所以下面将分别讲解迭代器和生成器这两个概念。

一. 迭代器(Iterator)

 写道
迭代器是一个对象,它实现了迭代器协议,
一般需要实现如下两个方法
1)next方法
返回容器的下一个元素
2)__iter__方法
返回迭代器自身

对于for语言大家可能都不陌生,我们很多时候需要对一些容器对象进行遍历就会使用到for循环:

  1. l=[0,1,2,3,4,5,6]
  2. for i in l:
  3. print i

l是一个type为list的对象,这段for-in代码在运行的时候其实是调用了l的__iter__()函数,返回了一个实现了__next__()或next()(各个版本的python可能不一样,我试验的时候所使用的版本为2.6.2)的迭代器对象,每循环一次就会通过next取下一个元素。

当然我们完全没有必要先把所有的元素都算出来放到一个list里或者其他容器类里进行循环,这样比较浪费空间。

我们可以直接创建自己的一个迭代器。

  1. # -*- coding: utf-8 -*-
  2. '''''Fibonacci iterator'''
  3. class Fib:
  4. '''''一个可以生成Fibonacci 数列的迭代器'''
  5. def __init__(self, max):
  6. self.max = max
  7. def __iter__(self):
  8. self.a = 0
  9. self.b = 1
  10. return self
  11. def next(self):
  12. fib = self.a
  13. if fib > self.max:
  14. raise StopIteration
  15. self.a, self.b = self.b, self.a + self.b
  16. return fib

定义好了这个Fibonacci迭代器,我们就可以来使用它了。

  1. from fibonacci2 import Fib
  2. for n in Fib(1000):
  3. print n

当调用Fib(1000)的时候,将生成一个迭代器对象,每一次循环都将调用一次next取到下一个值。

所以我们可以看出迭代器有一个很核心的东西就是在循环中,迭代器可以记住之前的状态。

二.生成器

前面我们说了,任何使用了yield关键字的函数都不再是普通的函数了,我们还是来看实例吧,这样比较容易理解

  1. def fib(max):
  2. a, b = 0, 1
  3. while a < max:
  4. yield a
  5. a, b = b, a + b

这里简单的几行代码就实现了上面的迭代器类那么一大堆代码所实现的功能

使用的时候和上面很类似:

  1. from fibonacci import fib
  2. for n in fib(1000):
  3. print n

引文fib函数使用了yield所以它是一个生成器函数,当我们调用fib(1000)的时候它其实是返回了一个迭代器,且这个迭代器可以控制生成器函数的运行。

我们通过这个返回的迭代器的动作控制fib这个生成器函数的运行。

每当调用一次迭代器的next函数,生成器函数运行到yield之处,返回yield后面的值且在这个地方暂停,所有的状态都会被保持住,直到下次next函数被调用,或者碰到异常循环退出。

所以生成器的概念还是很简单的。

三.总结

1.for-in语句在底层都是对一个迭代器对象进行操作的

2.使用了yield关键字的函数就是一个生成器函数,被调用的时候生成一个可以控制自己运行的迭代器。

从python的yield说起的更多相关文章

  1. Python关键字yield的解释(stackoverflow)

    3.1. 提问者的问题 Python关键字yield的作用是什么?用来干什么的? 比如,我正在试图理解下面的代码: def node._get_child_candidates(self, dista ...

  2. python 关键字yield解析

    python 关键字yield解析 yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator.y ...

  3. [转]Python中yield的解释

    转自: http://python.jobbole.com/83610/ 本文作者: 伯乐在线 - wklken .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 翻译 来源于stackover ...

  4. Python中yield和yield from的用法

    yield python中yield的用法很像return,都是提供一个返回值,但是yield和return的最大区别在于,return一旦返回,则代码段执行结束,但是yield在返回值以后,会交出C ...

  5. Python Deque 模块使用详解,python中yield的用法详解

    Deque模块是Python标准库collections中的一项. 它提供了两端都可以操作的序列, 这意味着, 你可以在序列前后都执行添加或删除. https://blog.csdn.net/qq_3 ...

  6. [翻译]Python中yield的解释

    问题: Python中yield关键字的作用是什么?它做了什么? 例如,我想理解以下代码 def node._get_child_candidates(self, distance, min_dist ...

  7. python 关键字yield

    问题 Python 关键字 yield 的作用是什么?用来干什么的? 比如,我正在试图理解下面的代码: def node._get_child_candidates(self, distance, m ...

  8. 深入理解python的yield和generator

    原文发表在我的博客主页,转载请注明出处 前言 没有用过的东西,没有深刻理解的东西很难说自己会,而且被别人一问必然破绽百出.虽然之前有接触过python协程的概念,但是只是走马观花,这两天的一次交谈中, ...

  9. 使用Python的yield实现流计算模式

    首先先提一下上一篇<如何猜出Y combinator>中用的方法太复杂了.其实在Lambda演算中实现递归的思想很简单,就是函数把自己作为第一个参数传入函数,然后后面就是简单的Lambda ...

  10. Python基础 (yield生成器)

    如果在一个函数中使用了yield,那么这个函数实际上生成的是一个生成器函数 ,返回的是一个generator object.生成器是实现迭代的一种方式 特点: 其实返回的就是可以的迭代对象 和迭代的方 ...

随机推荐

  1. linux上应用程序的执行机制

    linux上应用程序的执行机制 执行文件是如何在shell中被"执行"的.本文中尽可能少用一些源码,免得太过于无 聊,主要讲清这个过程,感兴趣的同学可以去查看相应的源码了解更多的信 ...

  2. ARM(ARM处理器)

    ARM是微处理器行业的一家英国公司,其设计了大量高性能.廉价.耗能低的RISC处理器.相关技术及软件,公司并不直接生产产品,而是采用出售芯片技术授权的商业模式盈利.技术具有性能高.成本低和能耗省特点. ...

  3. Android Handler与多线程

    本文首先解释一下handler是用来干嘛的,然后通过例子介绍其在多线程中的应用. 什么是Handler handler通俗一点讲就是用来在各个进程之间发送数据的处理对象.在任何进程中,只要获得了另一个 ...

  4. 未能加载文件或程序集“Interop.jmail”或它的某一个依赖项

    未能加载文件或程序集“Interop.jmail”或它的某一个依赖项.试图加载格式不正确的程序. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中 ...

  5. 一行很好的JS代码

    [].forEach.call($$("*"),function(a){ a.style.outline="1px solid #"+(~~(Math.rand ...

  6. 课程设计之(struts2+Hibernate)航空订票系统

    1.题目 课程设计之航空订票系统 为某家机票预订服务商开发一个机票预订和查询管理系统.该系统中的航班和机票信息由多家航空公司负责提供.客户通过上网方式查询航班时间表.机票可用信息.机票折扣信息,可以远 ...

  7. java服务器知识

    http://blog.csdn.net/chenyi8888/article/details/4484641 http://blog.csdn.net/chenyi8888/article/deta ...

  8. 1320. Graph Decomposition

    1320 简单并查集 #include <iostream> #include<cstdio> #include<cstring> #include<algo ...

  9. 1137. Bus Routes(dfs)

    1137 做过一样的 怎么又忘了 再一次搜超时 不用回溯 #include <iostream> #include<cstdio> #include<cstring> ...

  10. 50个python库

    50个很棒的Python模块,包含几乎所有的需要:比如Databases,GUIs,Images, Sound, OS interaction, Web,以及其他.推荐收藏. Graphical in ...