前段时间在读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关键字的函数就是一个生成器函数,被调用的时候生成一个可以控制自己运行的迭代器。

python yield原理_从python的yield说起相关推荐

  1. python 冒泡排序 原理_用Python实现排序算法——冒泡排序

    正在学习Python,然后呢,也想复习一下算法,所以采取这样的方式,一举两得.后面会用python逐步完成常用算法,算是学习笔记了. 贴代码之前还是先描述算法原理.冒泡的原理(以下描述为降序排序)是: ...

  2. python切片原理_分析python切片原理和方法

    使用索引获取列表的元素(随机读取) 列表元素支持用索引访问,正向索引从0开始 colors=["red","blue","green"] c ...

  3. python通信原理_用python通过原始套接字发送scapy包

    要使用原始套接字发送scapy数据包,必须先将数据包转换为原始字节.例如,使用scapy制作的数据包如下:p = IP(dst="192.168.1.254")/TCP(flags ...

  4. python 时间序列预测_使用Python进行动手时间序列预测

    python 时间序列预测 Time series analysis is the endeavor of extracting meaningful summary and statistical ...

  5. python 概率分布模型_使用python的概率模型进行公司估值

    python 概率分布模型 Note from Towards Data Science's editors: While we allow independent authors to publis ...

  6. python生成器单线程_「Python异步编程-3」协程、生成器、yield 的联系

    异步编程的基础在于理解协程,而协程的基础在于理解生成器,而生成器的基础在于理解yield关键字,下面就来说说这几个概念. 什么是yield关键字? 相当于return关键字,在每次next(),或者f ...

  7. python卡方检验筛选特征原理_基于Python的遥感特征筛选—递归特征消除(RFE)与极限树(Extra-Trees)...

    引言 基于前几篇文章关于筛选方法的介绍,本篇同样给大家介绍两种python封装的经典特征降维方法,递归特征消除(RFE)与极限树(Extra-Trees, ET).其中,RFE整合了两种不同的超参数, ...

  8. python解析原理_代码详解:Python虚拟环境的原理及使用

    Python的虚拟环境极大地方便了人们的生活.本指南先介绍虚拟环境的基础知识以及使用方法,然后再深入介绍虚拟环境背后的工作原理. 注意:本指南在macOS Mojave系统上使用最新版本的Python ...

  9. python程序运行原理_谈谈 Python 程序的运行原理

    因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,谈谈 Python 程序的运行原理 这篇文章准确说是『Python 源码剖析』的 ...

最新文章

  1. 数据结构与算法(5)字符串(BF算法、KMP算法及KMP算法优化)
  2. ajax 导出文件给 文件重新命名_Tanner LEdit 05 | 导出GDSII文件
  3. 网络推广公司介绍几个能提升网站收录的“隐藏版”小技巧!
  4. 数字发行:电子书、电影、游戏、音乐
  5. nodejs之express -- 1
  6. 获取本机IP地址[JavaScript / Node.js]
  7. 基于Yarp实现内网http穿透
  8. PHP单引号 ' ',没有任何意义,对所引内容不经任何处理直接拿过来
  9. TCP的可靠传输実现
  10. 不想打造物联网的制造型企业不是一家合格的百年老店
  11. 开发电脑应该是8核(8线)
  12. map分组后取前10个_35岁詹皇有多强?17年生涯首拿助攻王背后:10个月前早已定下目标...
  13. CC2530单片机入门学习
  14. IOI 2022国际信息学竞赛那些事儿(附Day1原题)
  15. gateway解决过滤器response返回中文乱码
  16. VPS云主机的定义和基本优势有哪些
  17. c语言帮助记忆单词的小程序,帮助记忆单词的书课堂活动微信小程序软件_速记背单词...
  18. 蓝桥冲刺31天打卡—Day14
  19. VS Code + Latex + SumatraPDF 环境(实用)
  20. Android USB开发小结:host模式与accessory模式

热门文章

  1. Integer的常用方法和String类型的常用方法
  2. 客户端连接故障检查流程手段
  3. shell读取php 数组长度,shell数组的定义、数组长度
  4. java生成动态验证码_java动态生成验证码
  5. amoeba实现mysql主从读写分离_利用Amoeba实现MySQL主从复制和读写分离
  6. c++篇 vc++2010设置和c#一样的代码段,vs2010 两下tab设置
  7. J2EE五层架构概念[转+整理]
  8. 原生js实现文字无缝向上滚动效果
  9. ios---NSNotificationCenter传值
  10. EularProject 39:给周长推断构成直角三角形个数