zoukankan      html  css  js  c++  java
  • 迭代器和可迭代对象

    from collections import Iterable, Iterator
    
    
    class ClassIterator:
        """迭代器必须实现__iter__和__next__方法,故迭代器一定是可迭代对象"""
        def __init__(self, obj):
            self.obj = obj
            self.position = 0
    
        def __iter__(self):
            pass
    
        def __next__(self):
            if self.position < len(self.obj.names):
                next_value = self.obj.names[self.position]
                self.position += 1
                return next_value
            else:
                raise StopIteration
    
    
    class ClassMate:
        """只要实现了__iter__方法就是可迭代对象,可迭代对象返回一个迭代器"""
        def __init__(self):
            self.names = ["zhang san", "li si", "wang wu"]
    
        def __iter__(self):
            return ClassIterator(self)
    
    
    classmate = ClassMate()
    class_iterator = ClassIterator(classmate)
    
    print(isinstance(classmate, Iterable))  # 返回True,因为实现了__iter__方法,所以是可迭代对象
    print(isinstance(classmate, Iterator))  # 返回false,因为没有实现__next__方法,所以不是迭代器
    print(isinstance(class_iterator, Iterable))  # 返回True,实现了__iter__
    print(isinstance(class_iterator, Iterator))  # 返回True,实现了__iter__和__next__
    
    """for语句首先用iter(classmate)获取一个迭代器,然后用next(迭代器)逐个获取元素,直到捕捉到StopIteration"""
    for i in classmate:
        print(i)

    总结:

    1、对象A重载了__iter__方法(甚至方法体是pass),那么A就是可迭代对象,即isinstance(A,Iterable)返回True

    2、对象A重载了__iter__方法和__next__方法,那么A就是一个迭代器,即isinstance(A,Iterator)返回True

    3、iter(A)触发A的__iter__方法,__iter__返回一个迭代器

    4、next(迭代器)触发迭代器的__next__方法

    5、for i in A的执行流程为:先调用iter(A)获取一个迭代器B,然后执行next(B),直到B抛出StopIteration异常

    事实上,迭代器和可迭代对象可以合二为一,当一个对象实现了__iter__和__next__,那么它既是可迭代对象,又是迭代器,__iter__可以返回它自己,而不需要额外去写一个迭代器,比如上面的示例可以简化为:

    class ClassMate:
        def __init__(self):
            self.names = ["zhang san", "li si", "wang wu"]
            self.position = 0
    
        def __iter__(self): # 本身是一个迭代器
            return self
    
        def __next__(self):
            if self.position < len(self.names):
                next_value = self.names[self.position]
                self.position += 1
                return next_value
            else:
                raise StopIteration
    
    
    classmate = ClassMate()
    
    for i in classmate:
        print(i)
  • 相关阅读:
    vue路由对象($route)参数简介
    原生js写ajax请求(复习)
    js,jq.事件代理(事件委托)复习。
    CSS 设置table下tbody滚动条
    H5 调用手机摄像机、相册功能
    css实现六边形图片(最简单易懂方法实现高逼格图片展示)
    input表单的type属性详解,不同type不同属性之间区别
    js对象,set和get方法 的三种实现形式
    day03 变量
    day01 js三种导入html的方法、js书写规范、变量的基本使用、变量提升
  • 原文地址:https://www.cnblogs.com/olivertian/p/12602399.html
Copyright © 2011-2022 走看看