`
lukejin
  • 浏览: 366113 次
  • 性别: 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)这个角度来看待,生成器就好像一个生产者,而所关联的那个迭代器就是一个消费者。

相关推荐

    0394-极智开发-解读python yield用法

    0394_极智开发_解读python yield用法

    Python yield 使用浅析

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

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

    Python库`ffmpeg_progress_yield`是用于处理多媒体文件的工具,特别是在视频和音频处理方面。它是一个基于Python的接口,能够与FFmpeg命令行工具进行交互,从而为用户提供更方便、更高级别的API来操作多媒体数据。`...

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

    在Python中,`yield`函数是生成器(generator)的核心组成部分,它允许函数成为一个可迭代的对象,而不是一次性返回所有结果。生成器是一种特殊的迭代器,它们不会立即计算所有的值,而是根据需要在运行时逐个生成。...

    python-yield用法详解.pdf

    # Python中的`yield`用法详解 ## 一、引言 在Python编程语言中,`yield`关键字是一个非常强大的特性,它使我们能够轻松地创建生成器(generators)。生成器是一种特殊的迭代器,可以让你在一个函数执行过程中保存...

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

    ### 基于Python Yield机制的异步操作同步化编程模型 #### 一、引言 随着现代软件系统越来越依赖于非阻塞式(异步)处理方式来提高效率和响应速度,同步与异步之间的转换变得尤为重要。本文将探讨如何利用Python中的...

    Python yield使用方法示例

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

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

    总结来说,Python的`yield`关键字和生成器提供了一种高效、内存友好的迭代方式,特别适用于处理大量数据流。与`return`相比,`yield`的优势在于它可以保存函数状态并在后续调用中恢复执行,这在需要分步处理或延迟...

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

    在Python编程语言中,全排列是指从一组给定的不同元素中选取所有可能的不重复排列。这个概念在解决各种组合问题、数据处理和算法设计中非常常见。在本例中,我们将探讨如何利用`yield`关键字来高效地生成一个数组的...

    Python yield与实现方法代码分析

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

    python中yield的用法详解——最简单,最清晰的解释

    ### Python中`yield`的关键概念与使用详解 #### 前言 在Python编程语言中,`yield`关键字提供了一种高效且灵活的方式来处理大型数据集或无限序列,尤其是在涉及迭代器、生成器等概念时更为突出。本文将详细介绍`...

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

    在Python编程语言中,`yield`关键字是用来创建生成器(generator)的重要工具,它与`return`类似但有所不同。生成器是一种特殊的迭代器,能够节省内存资源,因为它们不一次性生成所有值,而是按需生成。这篇文档主要...

    python 如何区分return和yield

    另一方面,`yield`关键字在Python中用于生成器(generator)函数,它返回一个生成器对象,该对象能够记住函数当前的执行状态,之后能够从上次离开的位置继续执行。每次遇到`yield`时,函数生成一个值并暂停执行,...

    Python yield 使用方法浅析

    - **状态保存**:每次调用`next()` 方法时,函数会从上次`yield` 处暂停的地方继续执行,并且函数内的局部变量状态会被保留下来,这使得我们可以轻松实现复杂的迭代逻辑。 #### 三、使用示例 接下来,我们将通过一...

    python中yield的用法详解1

    在Python编程语言中,`yield`关键字是一种特殊的功能,它被用于创建生成器(generator)。生成器是一种特殊的迭代器,可以动态地生成值,而无需一次性加载所有数据。这种特性在处理大量数据或无限序列时非常有用,...

    对python中return与yield的区别详解

    在Python编程语言中,`return` 和 `yield` 都是用来在函数中返回值的关键字,但它们之间存在显著的区别,这些差异对于理解和编写高效的代码至关重要。 首先,`return` 关键字用于从函数中返回一个值。当 `return` ...

    python中yield的用法.docx

    Python中的`yield`关键字是其语法的一大特色,它在生成器(Generator)中扮演着核心角色。生成器是一种特殊的迭代器,它允许我们定义一个函数,该函数可以在执行过程中暂停并保存状态,以便下次调用时能从暂停的地方...

    Python yield的用法实例分析

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

Global site tag (gtag.js) - Google Analytics