`
lukejin
  • 浏览: 362358 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

从python的yield说起

阅读更多

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

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

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

 

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

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

 

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

 

一. 迭代器(Iterator)

 

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

 

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

 

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

 

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

 

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

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

 

# -*- coding: utf-8 -*-

'''Fibonacci iterator'''

class Fib:
    '''一个可以生成Fibonacci 数列的迭代器'''

    def __init__(self, max):
        self.max = max

    def __iter__(self):
        self.a = 0
        self.b = 1
        return self

    def next(self):
        fib = self.a
        if fib > self.max:
            raise StopIteration
        self.a, self.b = self.b, self.a + self.b
        return fib
 

 

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

 

 

from fibonacci2 import Fib
for n in Fib(1000):
    print n

 

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

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

 

 

二.生成器

 

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

 

 

def fib(max):
    a, b = 0, 1          
    while a < max:
        yield a          
        a, b = b, a + b  

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

 

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

 

 

from fibonacci import fib
for n in fib(1000):
    print n

 

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

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

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

 

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

 

三.总结

 

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

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

 

分享到:
评论
6 楼 gmizr 2010-02-26  
使用yield未必会比自己写__init__,next速度慢,我也只是想当然,还没有实验过

python官方的tutorial也包含了yield的内容
9.10. Generators
5 楼 lzyzizi 2010-02-22  
对PYTHON的理解还不是很深,感觉yield和RUBY的yield有点像。
敢问楼上各位我是否可以把这里的yield看做是一个template或者visitor里的一个留个未来实现的“抽象函数”?
4 楼 lukejin 2010-02-21  
calmness 写道
yield是记住了多个断点的状态,那在性能上应该是比传统的迭代器速度慢

但是比传统的方便很多的。
3 楼 calmness 2010-02-21  
yield是记住了多个断点的状态,那在性能上应该是比传统的迭代器速度慢
2 楼 mikeandmore 2010-02-11  
lukejin 写道
其实呢 yield可以从协程(Coroutines)这个角度来看待,生成器就好像一个生产者,而所关联的那个迭代器就是一个消费者。

而且还是双向的-w-

1 楼 lukejin 2010-02-03  
其实呢 yield可以从协程(Coroutines)这个角度来看待,生成器就好像一个生产者,而所关联的那个迭代器就是一个消费者。

相关推荐

    Python yield 使用浅析

    初学 Python 的开发者经常会发现很多 Python 函数中用到了 yield 关键字,然而,带有 yield 的函数执行流程却和普通函数不一样,yield 到底用来做什么,为什么要设计 yield ?本文将由浅入深地讲解 yield 的概念和...

    python中yield的用法.docx

    Python是常用的一种编程语言,编程过程中,变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。 Python由荷兰数学和计算机科学研究学会的吉多·范罗...

    python-yield用法详解.pdf

    python方法 python_yield用法详解

    基于python yield机制的异步操作同步化编程模型

    主要介绍了基于python yield机制的异步操作同步化编程模型,需要的朋友可以参考下

    初步解析Python中的yield函数的用法

    主要介绍了Python中的yield函数,yield函数是生成器中的一个常用函数,本文来自于IBM官方网站的开发者文档的翻译,需要的朋友可以参考下

    Python yield使用方法示例

    叠代器工作在一个容器里(array[10]),它按一定顺序(i++)从容器里取出值(array[i])并进行操作(printf(“%d “, array[i])。 上面的代码翻译成python:  复制代码 代码如下: array = [i for i in range(10)]for i in...

    Python库 | ffmpeg_progress_yield-0.1.2-py2.py3-none-any.whl

    python库,解压后可用。 资源全名:ffmpeg_progress_yield-0.1.2-py2.py3-none-any.whl

    Python yield与实现方法代码分析

    yield的功能类似于return,但是不同之处在于它返回的是生成器。 生成器 生成器是通过一个或多个yield表达式构成的函数,每一个生成器都是一个迭代器(但是迭代器不一定是生成器)。 如果一个函数包含yield关键字,...

    python通过yield实现数组全排列的方法

    主要介绍了python通过yield实现数组全排列的方法,实例分析了全排列的概念及yield实现的技巧,具有一定参考借鉴价值,需要的朋友可以参考下

    Python yield生成器和return对比代码实例

    迭代是Python最强大的功能之一,是访问集合元素的一种方式。 迭代器是一个可以记住遍历的位置的对象。 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。 迭代器有两个...

    Python中yield返回生成器的详细方法.pdf

    Python中yield返回生成器的详细方法

    Python yield 使用方法浅析

    如何生成斐波那契數列 斐波那契(Fibonacci)數列是一个非常简单的递归数列,除第一个和第二个数外,任意一个数都可由前两个数相加得到。用计算机程序输出斐波那契數列的前 N 个数是一个非常简单的问题,许多初学者...

    Python yield的用法实例分析

    本文实例讲述了Python yield的用法。分享给大家供大家参考,具体如下: yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法。 只是粗略的知道yield可以用来为一个函数返回值塞...

    python yield关键词案例测试

    简单来说,yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator 代码演示 例子1: 输出斐波那契數列前 N 个数 #!/usr/bin/env python # ...

    举例详解Python中yield生成器的用法

    yield是生成的意思,但是在python中则是作为生成器理解,生成器的用处主要可以迭代,这样简化了很多运算模型(还不是很了解是如何简化的)。 yield是一个表达式,是有返回值的. 当一个函数中含有yield时,它不再是一个...

    python 如何区分return和yield

    主要介绍了python 如何区分return和yield,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下

Global site tag (gtag.js) - Google Analytics