参考链接: Python __iter __()和__next __()| 将对象转换为迭代器

文章目录

`__iter__` 和 `__next__`真正的迭代器总结

python里面有很多的以__开始和结尾的函数,利用它们可以完成很多复杂的逻辑代码,而且提高了代码的简洁性,本文主要总结了迭代器用到的魔术方法,并且主要以代码例子进行解释。

__iter__ 和 __next__

其实这里需要引入一个概念,叫迭代器,常见的就是我们在使用for语句的时候,python内部其实是把for后面的对象上使用了内建函数iter,比如:

a = [1, 2, 3]

for i in a:

do_something()

其实在python内部进行了类似如下的转换:

a = [1, 2, 3]

for i in iter(a):

do_something()

那么iter返回的是什么呢,就是一个迭代对象,它主要映射到了类里面的__iter__函数,此函数返回的是一个实现了__next__的对象。注意理解这句话,比如:

class B(object):

def __next__(self):

raise StopIteration

class A(object):

def __iter__(self):

return B()

我们可以看见,A这个类实现了一个__iter__函数,返回的是B()的实例对象,其中B里面实现了__next__这个函数。

下面引入几个概念: Iterable: 有迭代能力的对象,一个类,实现了__iter__,那么就认为它有迭代能力,通常此函数必须返回一个实现了__next__的对象,如果自己实现了,你可以返回self,当然这个返回值不是必须的; Iterator: 迭代器(当然也是Iterable),同时实现了__iter__和__next__的对象,缺少任何一个都不算是Iterator,比如上面例子中,A()可以是一个Iterable,但是A()和B()都不能算是和Iterator,因为A只实现了__iter__,而B只实现了__next__()。

我们可以使用collections里面的类型来进行验证:

class B(object):

def __next__(self):

raise StopIteration

class A(object):

def __iter__(self):

return B()

from collections.abc import *

a = A()

b = B()

print(isinstance(a, Iterable))

print(isinstance(a, Iterator))

print(isinstance(b, Iterable))

print(isinstance(b, Iterator))

结果是:

True

False

False

False

让我们稍微对B这个类做一点修改:

class B(object):

def __next__(self):

raise StopIteration

def __iter__(self):

return None

class A(object):

def __iter__(self):

return B()

from collections.abc import *

a = A()

b = B()

print(isinstance(a, Iterable))

print(isinstance(a, Iterator))

print(isinstance(b, Iterable))

print(isinstance(b, Iterator))

结果是:

True

False

True

True

真正的迭代器

上面只是做了几个演示,这里具体说明一下: 当调用iter函数的时候,生成了一个迭代对象,要求__iter__必须返回一个实现了__next__的对象,我们就可以通过next函数访问这个对象的下一个元素了,并且在你不想继续有迭代的情况下抛出一个StopIteration的异常(for语句会捕获这个异常,并且自动结束for),下面实现了一个自己的类似range函数的功能。

class MyRange(object):

def __init__(self, end):

self.start = 0

self.end = end

def __iter__(self):

return self

def __next__(self):

if self.start < self.end:

ret = self.start

self.start += 1

return ret

else:

raise StopIteration

from collections.abc import *

a = MyRange(5)

print(isinstance(a, Iterable))

print(isinstance(a, Iterator))

for i in a:

print(i)

结果是:

True

True

0

1

2

3

4

接下来我们使用next函数模拟一次:

class MyRange(object):

def __init__(self, end):

self.start = 0

self.end = end

def __iter__(self):

return self

def __next__(self):

if self.start < self.end:

ret = self.start

self.start += 1

return ret

else:

raise StopIteration

a = MyRange(5)

print(next(a))

print(next(a))

print(next(a))

print(next(a))

print(next(a))

print(next(a)) # 其实到这里已经完成了,我们在运行一次查看异常

可以看见一个很明显的好处是,每次产生的数据,是产生一个用一个,什么意思呢,比如我要遍历[0, 1, 2, 3.....]一直到10亿,如果使用列表的方式,那么是会全部载入内存的,但是如果使用迭代器,可以看见,当用到了(也就是在调用了next)才会产生对应的数字,这样就可以节约内存了,这是一种懒惰的加载方式。

总结

可以使用collection.abs里面的Iterator和Iterable配合isinstance函数来判断一个对象是否是可迭代的,是否是迭代器对象iter实际是映射到了__iter__函数只要实现了__iter__的对象就是可迭代对象(Iterable),正常情况下,应该返回一个实现了__next__的对象(虽然这个要求不强制),如果自己实现了__next__,当然也可以返回自己同时实现了__iter__和__next__的是迭代器(Iterator),当然也是一个可迭代对象了,其中__next__应该在迭代完成后,抛出一个StopIteration异常for语句会自动处理这个StopIteration异常以便结束for循环

生成器相关的文档已经在这里。

[转载] 【python魔术方法】迭代器(__iter__和__next__)相关推荐

  1. Python 魔术方法指南

    http://pycoders-weekly-chinese.readthedocs.org/en/latest/issue6/a-guide-to-pythons-magic-methods.htm ...

  2. python 魔术方法

    python 魔术方法 常用魔术方法 魔术方法就是一个类的特殊方法,和普通方法唯一的不同时,普通方法需要调用!而魔术方法由系统自动调用. 1.__init__ 初始化魔术方法 触发时机:初始化对象时触 ...

  3. 【Python魔术方法】py复习

    Python魔术方法 __init__ 类似于构造器 #__init__ magic class Human:def __init__(self, name):#print('init exec')s ...

  4. python魔术方法abstract_python学习之面向对象高级特性和魔术方法

    01_property商品应用.py 分页显示是一种非常常见的浏览和显示大量数据的方法,属于web编程中最常处理的事件之一. 类属性应用需求: 对于京东商城中显示电脑主机的列表页面,每次请求不可能把数 ...

  5. python魔术方法(进阶)斐波那契数列

    文章目录 特殊属性 查看属性 实例化 可视化 hash bool 运算符重载应用场景 容器相关方法 可调用对象 上下文管理 上下文管理的安全性 方法的参数 contextlib.contextmana ...

  6. python魔术方法print_Python中的魔术方法入门

    介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",中文称『魔术方法』,例如类的初始化方法 __init__ ,P ...

  7. python魔术方法由谁定义_Python的魔术方法

    魔术方法就是在定义的类中定义一些"不一般"的方法,使类的使用更方便.完善.健壮,是python特有的方法,一般都是前后包含两个下划线__的方法称为魔术方法,例如__new__. 基 ...

  8. [转载] Python 学习笔记 迭代器和生成器

    参考链接: Python中的迭代器函数2(islice(),starmap(),tee()..) 本文链接地址 http://quqiuzhu.com/2016/python-iterator-and ...

  9. python魔术方法是什么_Python常用魔术方法

    什么是魔术方法? 在Python中,所有以双下划线__包起来的方法,统称为Magic Method(魔术方法),它是一种的特殊方法,普通方法需要调用,而魔术方法不需要调用就可以自动执行. 魔术方法在类 ...

最新文章

  1. 一次改变未来10年人生的机会
  2. Guava 源码分析(Cache 原理)
  3. linux 命令改配置文件,linux下 修改配置文件的命令
  4. vim 的substitute
  5. Gradle接口:Gradle构建元数据
  6. 基于jQuery实现水平轮播效果
  7. python利用myqr库生成二维码
  8. CMS 平台: Drupal, eZ Publish, WordPress, CMS Made Simple 横向比较
  9. Python变量的下划线
  10. 怎样用计算机算出圆周率,古代没有计算机的时代 祖冲之是如何算出圆周率的...
  11. php-学通PHP的24堂课-设置PHP的系统当前时间
  12. Confluence 6 使用 Decorator 宏
  13. web版pdf在线阅读器
  14. 关于怎么查看自己电脑正版windows的产品密钥
  15. matlab 矩阵除法求方程组的解,线性方程组求解矩阵除法.PPT
  16. python 存储bmp格式图片
  17. 差钱吗?周杰伦线上演唱会没关打赏惹争议,看看同时直播的腾格尔
  18. 「迁怒」也许不只是没忍住
  19. 反超7-11!中国新的“便利店之王”即将诞生!
  20. Spring-IOC—基于XML配置Bean

热门文章

  1. c语言2048项目报告,c语言----项目_小游戏2048
  2. linux下drcom无法上网,drcom为什么还是不能上网啊!
  3. python如何导入图片imread_OpenCV 使用imread()函数读取图片的六种正确姿势
  4. excel单元格斜线_怎么在excel中画斜线?怎么在excel表格中画斜线?
  5. jspdf html转换pdf,使用jspdf将HTML转换为pdf时出错
  6. lableimg闪退_CV学习笔记(二十五):数据集标注与制作
  7. java 建造者实际中的用法_java中j建造者模式详解和使用方法
  8. 什么叫组网_家庭wifi,如何组网最合适
  9. 配置文件bashrc与profile的区别
  10. 正则表达式和grep