Python生成器generator原理及用法解析


Posted in Python onJuly 20, 2020

前言

生成器generator

生成器的本质是一个迭代器(iterator)

要理解生成器,就要在理解一下迭代,可迭代对象,迭代器,这三个概念

Python生成器generator简介

iteration, iterable, iterator

迭代(iteration):在python中迭代通常是通过for...in...来实现的.而且只要是可迭代对象iterable,都能进行迭代.

可迭代对象(iterable):Python中的任意的对象,只要它定义了可以返回一个迭代器的 __iter__方法,或者定义了可以支持下标索引的__getitem __方法,那么它就是一个可迭代对象。简单说,可迭代对象就是能提供迭代器的任意对象.返回的是一个iterator 对象.官方解释

迭代器(iterator ) : 简单的说,迭代器就是实现了iterator.__iter__() 和iterator.__next__() 的对象,iterator.__iter__()方法返回的是iterator对象本身.根据官方的说法,正是这个方法,实现了for ... in ...语句.而iterator.__next__()是iterator区别于iterable的关键了,它允许我们显式地获取一个元素.当调用next()方法时,实际上产生了2个操作:

更新iterator状态,令其指向后一项,以便下一次调用,每一个值过后,指针移动到下一位,对iterator遍历完后,其变成了一个空的容器,但不是None ,需要注意的是,迭代结束后,指针不会自动返回到首位,而是依旧停留在末位置,想要在开始,需要重新载入迭代对象.

实例理解:

>>> from collections import Iterable, Iterator
 >>> a = [1,2,3]  # 众所周知,list是一个iterable
 >>> b = iter(a)  # 通过iter()方法,得到iterator,iter()实际上调用了__iter__(),
 >>> isinstance(a, Iterable)
 True
 >>> isinstance(a, Iterator)
 False
 >>> isinstance(b, Iterable)
 True
 >>> isinstance(b, Iterator)
 True

可见,itertor 一定是iterable ,但iterable不一定是itertor

>>> dir(a)
 ['__add__','__class__','__contains__','__delattr__','__delitem__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__getitem__','__gt__','__hash__','__iadd__','__imul__','__init__','__iter__','__le__','__len__','__lt__','__mul__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__', '__reversed__','__rmul__', '__setattr__','__setitem__','__sizeof__','__str__', '__subclasshook__','append','clear' 'copy','count','extend','index','insert', 'pop','remove', 'reverse','sort']
 
 >>>dir(b)
 ['__class__','__delattr__', '__dir__', '__doc__','__eq__', '__format__','__ge__' ,'__getattribute__', '__gt__','__hash__','__init__','__iter__','__le__','__length_hint__',
 '__lt__','__ne__','__new__','__next__','__reduce__','__reduce_ex__','__repr__','__setattr__', '__setstate__','__sizeof__','__str__','__subclasshook__']

可以看到迭代器具有__next__ 这个方法,可迭代对象具有__getitem__

迭代器是消耗型的,随着指针的移动,遍历完毕以后,就为空,但是不是None

>>> c = list(b)
 >>> c
 [1, 2, 3]
 >>> d = list(b)
 >>> d
 []
 
 
 # 空的iterator并不等于None.
 >>> if b:
 ...  print(1)
 ...
 1
 >>> if b == None:
 ...  print(1)
 ...

使用迭代器的内置方法 __next__ 和 next() 方法,遍历元素

In [73]: e = iter(a)
 
 In [74]: next(e)
 Out[74]: 1
 
 In [75]: e.__next__
 Out[75]: <method-wrapper '__next__' of list_iterator object at 0x7f05571c8518>
 
 In [76]: e.__next__()
 Out[76]: 2
 
 In [77]: e.__next__()
 Out[77]: 3
 
 In [78]: e.__next__()
 ---------------------------------------------------------------------------
 StopIteration               Traceback (most recent call last)
 <ipython-input-78-6024b5bd9bd2> in <module>()
 ----> 1 e.__next__()
 StopIteration:

当遍历完毕时,会返回一个StopIteration 的错误.

for...in.... 遍历迭代

当我们对一个iterable 使用for ....in... 进行遍历时,实际上是想调用iter() 方法得到一个iterator ,假设为x ,然后循环的调用x 的__next__() (next())方法,取得每一次的值,直到iterator为空,返回StopIteration 作为循环的结束的标准.for....in...会自动处理 StopIteration 异常,从而避免了抛出异常,从而使程序中断.流程图为:

x = [1, 2, 3]
for i in x:
print(x)

Python生成器generator原理及用法解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python的randrange()方法使用教程
May 15 Python
python字典多键值及重复键值的使用方法(详解)
Oct 31 Python
Python中正则表达式详解
May 17 Python
Python统计单词出现的次数
Apr 04 Python
mac安装scrapy并创建项目的实例讲解
Jun 13 Python
python实现串口自动触发工作的示例
Jul 02 Python
Python循环结构的应用场景详解
Jul 11 Python
基于sklearn实现Bagging算法(python)
Jul 11 Python
如何使用python操作vmware
Jul 27 Python
python使用 __init__初始化操作简单示例
Sep 26 Python
简单了解Django ORM常用字段类型及参数配置
Jan 07 Python
Win10环境中如何实现python2和python3并存
Jul 20 #Python
python和go语言的区别是什么
Jul 20 #Python
Python基础教程(一)——Windows搭建开发Python开发环境
Jul 20 #Python
Python字典fromkeys()方法使用代码实例
Jul 20 #Python
Python爬虫设置ip代理过程解析
Jul 20 #Python
Python如何使用27行代码绘制星星图
Jul 20 #Python
tensorflow基于CNN实战mnist手写识别(小白必看)
Jul 20 #Python
You might like
剖析 PHP 中的输出缓冲
2006/12/21 PHP
php实现memcache缓存示例讲解
2013/12/04 PHP
PHP实现的购物车类实例
2015/06/17 PHP
PHP结合Ueditor并修改图片上传路径
2016/10/16 PHP
Lazy Load 延迟加载图片的 jQuery 插件
2010/02/06 Javascript
图片在浏览器中底部对齐 解决方法之一
2011/11/30 Javascript
document.documentElement的一些使用技巧
2013/04/18 Javascript
javascript获取网页中指定节点的父节点、子节点的方法小结
2013/04/24 Javascript
js中iframe调用父页面的方法
2014/10/30 Javascript
js实现缓冲运动效果的方法
2015/04/10 Javascript
JavaScript中的parse()方法使用简介
2015/06/12 Javascript
基于javascript代码检测访问网页的浏览器呈现引擎、平台、Windows操作系统、移动设备和游戏系统
2015/12/03 Javascript
Javascript从数组中随机取出不同元素的两种方法
2016/09/22 Javascript
Vue项目webpack打包部署到服务器的实例详解
2017/07/17 Javascript
Bootstrap 树控件使用经验分享(图文解说)
2017/11/06 Javascript
详解NODEJS的http实现
2018/01/04 NodeJs
ES6知识点整理之模块化的应用详解
2019/04/15 Javascript
[00:27]DOTA2次级职业联赛 - Lilith战队宣传片
2014/12/01 DOTA
[02:42]决战东方!DOTA2亚洲邀请赛重启荣耀之争
2017/03/17 DOTA
深入浅析python中的多进程、多线程、协程
2016/06/22 Python
Python基于回溯法子集树模板解决马踏棋盘问题示例
2017/09/11 Python
在Windows中设置Python环境变量的实例讲解
2018/04/28 Python
Flask框架信号用法实例分析
2018/07/24 Python
浅谈图像处理中掩膜(mask)的意义
2020/02/19 Python
Jupyter notebook 远程配置及SSL加密教程
2020/04/14 Python
详解Python 中的容器 collections
2020/08/17 Python
python opencv pytesseract 验证码识别的实现
2020/08/28 Python
HTML5 visibilityState属性详细介绍和使用实例
2014/05/03 HTML / CSS
美国女性奢华品牌精品店:INTERMIX
2017/10/12 全球购物
美国婴儿和儿童家具网上商店:ABaby.com
2018/07/02 全球购物
实习生体会的自我评价范文
2013/11/28 职场文书
汽车广告策划方案
2014/05/31 职场文书
娱乐节目策划方案
2014/06/10 职场文书
党员民主评议个人总结
2014/10/20 职场文书
2016新教师培训心得体会范文
2016/01/08 职场文书
Pycharm远程调试和MySQL数据库授权问题
2022/03/18 MySQL