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 相关文章推荐
pyqt4教程之widget使用示例分享
Mar 07 Python
Python 的 with 语句详解
Jun 13 Python
以Python的Pyspider为例剖析搜索引擎的网络爬虫实现方法
Mar 30 Python
Django 登陆验证码和中间件的实现
Aug 17 Python
python读取并写入mat文件的方法
Jul 12 Python
对于Python深浅拷贝的理解
Jul 29 Python
python pillow模块使用方法详解
Aug 30 Python
python下载库的步骤方法
Oct 12 Python
Python基础之函数原理与应用实例详解
Jan 03 Python
Python批量启动多线程代码实例
Feb 18 Python
jupyter notebook 的工作空间设置操作
Apr 20 Python
Pyhton爬虫知识之正则表达式详解
Apr 01 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使用curl存储cookie的示例
2014/03/31 PHP
PHP实现手机号码中间四位用星号(*)隐藏的自定义函数分享
2014/09/27 PHP
Yii框架登录流程分析
2014/12/03 PHP
php实现头像上传预览功能
2017/04/27 PHP
php判断某个方法是否存在函数function_exists (),method_exists()与is_callable()区别与用法解析
2020/04/20 PHP
jquery插件 cluetip 关键词注释
2010/01/12 Javascript
jQuery div层的放大与缩小简单实现代码
2013/03/28 Javascript
javascript浏览器兼容教程之事件处理
2014/06/09 Javascript
extjs 如何给column 加上提示
2014/07/29 Javascript
JS弹出新窗口被拦截的解决方法
2016/08/09 Javascript
JavaScript计算值然后把值嵌入到html中的实现方法
2016/10/29 Javascript
微信小程序 自定义对话框实例详解
2017/01/20 Javascript
jquery在启动页面时,自动加载数据的实例
2018/01/22 jQuery
解决vue项目中type=”file“ change事件只执行一次的问题
2018/05/16 Javascript
详解vue中async-await的使用误区
2018/12/05 Javascript
vue路由前进后退动画效果的实现代码
2018/12/10 Javascript
Fetch超时设置与终止请求详解
2019/05/18 Javascript
vue悬浮可拖拽悬浮按钮的实例代码
2019/08/20 Javascript
vue滚动插件better-scroll使用详解
2019/10/18 Javascript
解决Can't find variable: SockJS vue项目的问题
2020/09/22 Javascript
vue-drawer-layout实现手势滑出菜单栏
2020/11/19 Vue.js
python计算圆周长、面积、球体体积并画出圆
2014/04/08 Python
Python实现生成简单的Makefile文件代码示例
2015/03/10 Python
python使用datetime模块计算各种时间间隔的方法
2015/03/24 Python
在scrapy中使用phantomJS实现异步爬取的方法
2018/12/17 Python
根据tensor的名字获取变量的值方式
2020/01/04 Python
Python对excel的基本操作方法
2021/02/18 Python
利用CSS3实现进度条的两种姿势详解
2017/03/21 HTML / CSS
巧用HTML5给按钮背景设计不同的动画简单实例
2016/08/09 HTML / CSS
Doyoueven官网:澳大利亚健身服饰和配饰品牌
2019/03/24 全球购物
党员民主生活会个人整改措施材料
2014/09/16 职场文书
购房委托书
2014/10/15 职场文书
个人批评与自我批评总结
2014/10/17 职场文书
2015年学校信息技术工作总结
2015/05/25 职场文书
初中运动会前导词
2015/07/20 职场文书
小学语文的各类谚语(70首)
2019/08/15 职场文书