搞懂python中的可迭代对象和迭代器对象(即迭代器)

可迭代的对象和迭代器解惑:

可迭代的对象:常见的可以被for循环迭代的一些数据类型都是可迭代的对象,如列表,元组,字典,集合,字符串,生成器,range函数生成的数列等,从广泛的意义
上来说,这些对象都有一个内置的iter方法,且该方法可以返回一个迭代器对象,当用iter(可迭代对象)调用这个对象时,会返回一个迭代器对象(属于Iterator类)

for语句的原理就是先用iter函数获取可迭代对象的迭代器,然后调用next函数,此函数自动调用迭代器对象的next方法,每次遍历都返回相应的值,如果没有返回值了,就会抛出StopIter异常for语句自动捕获异常并处理

迭代器:

在Python3中,实现了next方法和方法iter方法,并且这个iter这个方法返回了值的对象,就叫做迭代器或者迭代器对象。
判断可迭代对象和迭代器,从collections导入Iterable,Iterator,用isinstance判断
根据以上的介绍,我们可以按照这个思路实现自定义的迭代器

模拟for语句底层的原理:

写两个类分别重写iter方法和next方法

#迭代器对象类

class MyRangeIterator(object):
    def __init__(self, start, end):
        self.index = start
        self.end = end

    def __next__(self):
        if self.index < self.end:
            temp = self.index
            self.index += 1
            return temp
        else:
            raise StopIteration()

#可迭代对象类

class MyRangeIterable(object):
    def __init__(self, start, end):
        self.start = start
        self.end = end

    def __iter__(self):
        # 该方法返回迭代器对象
        return MyRangeIterator(self.start, self.end)

#1.直接采用for遍历可迭代对象:

for i in MyRangeIterable(1, 10):
    print(i)

#2.for底层的原理,for到底干了哪些事情:
#第一步,iter函数获取迭代器对象:

ret_iterator = iter(MyRangeIterable(1,10))
while True:
    try:
        x = next(ret_iterator) #或者ret_iterator.__next__,实际iter函数和next函数都会反射去执行对象的__next__和__iter__方法,道理一样
        print(x)
    #如果迭代器没有返回值了就抛出异常,退出死循环
    except StopIteration:
        break

有的时候,我们会将iter方法和next方法写到一类里,这时类创建的对象有两个身份,既是可迭代对象,又是迭代器对象,和上面分开实现有稍微的区别,比如对文件读写时,我们打开一个文件产生的对象就是属于可迭代对象,也属于迭代器对象,可以通过dir查看到,它既有iter方法,也有next方法,而列表,元组则有点不一样,他们是可迭代对象,可以通过dir查看到它有iter方法,但没有next方法,所以还不是一个迭代器,需要通过iter函数调用对象,然后返回的才是可迭代器对象

在一个类中实现iter和next方法,把上面MyTRangeIterator next的代码挪到下面MyRangeIterable中,MyRangeIterable中返回自身就可以了

print(‘----第二种实现迭代器的类---‘)
class MyRangeIterable(object):
    def __init__(self, start, end):
        # self.start = start
        self.end = end
        self.index = start

    def __iter__(self):
        # 返回对象本身作为迭代器对象
        return self

    def __next__(self):
        if self.index < self.end:
            temp = self.index
            self.index += 1
            return temp
        else:
            raise StopIteration()

my_range = MyRangeIterable(1,20)
for i in my_range:
    print(i)

以上就是在一个类中实现的迭代器,它既是一个可迭代对象,也是一个迭代器对象,但是有个缺点,这个类创建出来的对象只能被遍历一轮,因为在最后index变量的值已经到底了,你再遍历这个对象是没有值的;但是分开实现的迭代器就没有这个问题,因为每次都进行了初始化

原文地址:https://blog.51cto.com/13560219/2446456

时间: 2024-11-07 11:19:33

搞懂python中的可迭代对象和迭代器对象(即迭代器)的相关文章

探寻Python中如何同时迭代多个iterable对象

题外话: 最近因为课程需要开始深入了解Python语言.因为以前一直用的Java.C++等强类型的静态语言,现在突然使用Python确实感受到了很大的不同. 直观感觉就是,在Python中总是能找到一些让代码变得精巧.简洁.高效.美观的写法,使得初学者在写代码的过程充满了惊喜,从而渐渐喜欢上Python.而且Python的官方手册阅读起来感觉非常好,很多问题都描述的很清楚.不过总体来说,还是觉得Java大法好:) Python中一个非常有用的语法就是for in循环跟iterable对象的结合,

轻松搞懂Java中的自旋锁

前言 在之前的文章<一文彻底搞懂面试中常问的各种"锁">中介绍了Java中的各种"锁",可能对于不是很了解这些概念的同学来说会觉得有点绕,所以我决定拆分出来,逐步详细的介绍一下这些锁的来龙去脉,那么这篇文章就先来会一会"自旋锁". 正文 出现原因 在我们的程序中,如果存在着大量的互斥同步代码,当出现高并发的时候,系统内核态就需要不断的去挂起线程和恢复线程,频繁的此类操作会对我们系统的并发性能有一定影响.同时聪明的JVM开发团队也发现,

真正搞明白Python中Django和Flask框架的区别

在谈Python中Django框架和Flask框架的区别之前,我们需要先探讨如下几个问题. 一.为什么要使用框架? 为了更好地阐述这个问题,我们把开发一个应用的过程进行类比,往往开发一个应用(web应用.系统应用)跟建造房子的过程一样,需要先打地基,搭好骨架,然后一块砖一块砖叠上去. 而开发一个应用呢?同样也需要一个好的架构设计,数据库建模,然后一个模块一个模块使用代码实现. 如果开发一个软件应用不使用框架,和我们建房子时,每一块砖.每一根钢筋都需要自己生产出来本质上是一样的. 显而易见,如果在

分分搞懂c#中的委托

分分搞懂c#中的委托: 不说废话,不来虚的概念,不管代码是否有意义,看我的优化之路,你会理解委托了: 源代码1 public class test { //我们不管代码是否有意义,我们直接看代码重构和一步步优化的过程 int flage = 1; public void show(int a) { if (flage == 1) { do1(a); } else if (flage == 2) { do2(a); } else if (flage == 3) { do3(a); } else i

Python中的可迭代对象与迭代器对象

刚刚学习Python,对“可迭代对象”和"迭代器对象"的个人理解,不知道对不对. 1.几个概念 1.迭代工具:包括for循环.列表解析.in成员关系测试.....等等在内的,用于依次访问可迭代对象(容器)内元素的操作(?). 2.迭代器对象:具有__next__()方法的对象.该方法能够自动返回下一个结果,当到达序列结尾时,引发StopIteration异常. 3.可迭代对象:具有__iter__()方法的对象.该方法可获取其迭代器对象. 2.迭代过程(以for循环为例) for循环开

大白话讲解Promise(三)搞懂jquery中的Promise

http://www.cnblogs.com/lvdabao/p/jquery-deferred.html @吕大豹 前两篇我们讲了ES6中的Promise以及Promise/A+规范,在Promise的知识体系中,jquery当然是必不可少的一环,所以本篇就来讲讲jquery中的Promise,也就是我们所知道的Deferred对象. 事实上,在此之前网上有很多文章在讲jquery Deferred对象了,但是总喜欢把ajax和Deferred混在一起讲,容易把人搞混.when.done.pr

一文彻底搞懂面试中常问的各种“锁”

前言 锁,顾名思义就是锁住一些资源,当只有我们拿到钥匙的时候,才能操作锁住的资源.在我们的Java,数据库,还有一些分布式的环境中,总是充斥着各种各样的锁让人头疼,例如“公平锁”.“自旋锁”.“读写锁”.“分布式锁”等等. 其实真实的情况是,锁并没有那么多,很多概念只是从不同的功能特性,设计,以及锁的状态这些不同的侧重点来说明的,因此我们可以根据不同的分类来搞明白为什么会有这些“锁”?坐稳扶好了,准备开车. 正文 “公平锁”与“非公平锁” 公平锁:指线程在等待获取同一个锁的时候,是严格按照申请锁

python中通过元类(TYPE)简单实现对象关系映射(ORM)

ORM是创建一个实例对象,用创建他的类名当做数据表名,用创建他的类属性对应数据表的字段,不需要在自己写复杂的sql语句,而是通过对实例对象的操作时,能让代码自动帮我们整理为对应的sql语句. class User(父类): uid = ("uid", "int unsigned") name = ("username", "varchar(20)") password = ("password", &quo

帮你搞懂Python进程,线程与协程

本文参考原文-http://bjbsair.com/2020-03-22/tech-info/4425/在操作系统中,每一个独立运行的程序,都占有 操作系统 分配的资源,这些程序中间互不干涉,都只负责运行自己的程序代码,这就是进程. 但是当操作系统频繁的创建销毁进程时,大量的系统资源被浪费在创建和销毁的过程中.而随着多核心 cpu 的出现,线程也逐渐代替了进程,成为了操作系统 可以独立运行的基本单位. 当进程不是多线程程序时,存在于进程当中的唯一线程,便是进程本身运行的代码块. 而当多线程出现在