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

作者:吃着东西不想停 时间:2021-10-14 14:00:13 

前言

生成器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原理及用法解析

来源:https://www.cnblogs.com/zwhy8/p/13336400.html

标签:Python,生成器,generator
0
投稿

猜你喜欢

  • 怎样设置密码保护问题

    2009-02-16 13:12:00
  • 解读python中的类型提示(type hint)

    2023-07-15 20:16:27
  • Jupyter加载文件的实现方法

    2021-11-12 23:16:15
  • 微信昵称带符号导致插入MySQL数据库时出错的解决方案

    2024-01-20 23:40:20
  • python分析网页上所有超链接的方法

    2021-03-15 05:28:08
  • python编译pyc文件的过程解析

    2022-08-13 20:48:19
  • 带进度条的ASP无组件断点续传大文件下载

    2010-06-25 18:27:00
  • ubuntu下设置mysql自动备份的例子

    2024-01-21 18:09:08
  • 在Django中进行用户注册和邮箱验证的方法

    2022-02-01 16:18:35
  • python文件选择对话框的操作方法

    2023-08-02 16:27:21
  • MySQL binlog_ignore_db 参数的具体使用

    2024-01-20 12:32:59
  • SQL Server查询结果导出到EXCEL表格的图文教程

    2024-01-23 10:40:22
  • Bootstrap表格和栅格分页实例详解

    2024-04-10 13:51:05
  • Python socket实现的文件下载器功能示例

    2021-03-12 22:43:19
  • MySQL创建用户和权限管理的方法

    2024-01-21 12:08:58
  • Python json解析库jsonpath原理及使用示例

    2022-05-18 09:43:00
  • 用Python代码自动生成文献的IEEE引用格式的实现

    2021-05-26 15:24:49
  • JS代码格式化和语法着色V2

    2023-07-02 05:18:27
  • python使用 request 发送表单数据操作示例

    2022-08-06 07:31:07
  • 在Django中管理Users和Permissions以及Groups的方法

    2023-11-03 03:10:21
  • asp之家 网络编程 m.aspxhome.com