zoukankan      html  css  js  c++  java
  • python 迭代器(三):迭代器基础(三)典型的迭代器

    标准迭代器

    示例 14-4 sentence_iter.py:使用迭代器模式实现 Sentence 类

    import re
    import reprlib
    
    RE_WORD = re.compile('w+')
    
    class Sentence:
    
        def __init__(self, text):
            self.text = text
            self.words = RE_WORD.findall(text)
    
        def __repr__(self):
            return 'Sentence(%s)' % reprlib.repr(self.text)
        def __iter__(self):  ➊
            return SentenceIterator(self.words)  ➋
    
    class SentenceIterator:
    
        def __init__(self, words):
            self.words = words  ➌
    
            self.index = 0  ➍
        def __next__(self):
            try:
                word = self.words[self.index]  ➎
            except IndexError:
                raise StopIteration()  ➏
            self.index += 1return word  ➑
        def __iter__(self):  ➒
            return self

    ❶ 与前一版相比,这里只多了一个 __iter__ 方法。这一版没有__getitem__ 方法,为的是明确表明这个类可以迭代,因为实现了__iter__ 方法。
    ❷ 根据可迭代协议,__iter__ 方法实例化并返回一个迭代器。
    ❸ SentenceIterator 实例引用单词列表。
    ❹ self.index 用于确定下一个要获取的单词。
    ❺ 获取 self.index 索引位上的单词。
    ❻ 如果 self.index 索引位上没有单词,那么抛出 StopIteration 异常。
    ❼ 递增 self.index 的值。
    ❽ 返回单词。
    ❾ 实现 self.__iter__ 方法。

    注意,对这个示例来说,其实没必要在 SentenceIterator 类中实现__iter__ 方法,不过这么做是对的,因为迭代器应该实现 __next__和 __iter__ 两个方法,

    而且这么做能让迭代器通过issubclass(SentenceInterator, abc.Iterator) 测试。

    如果让SentenceIterator 类继承 abc.Iterator 类,那么它会继承abc.Iterator.__iter__ 这个具体方法。

    把Sentence变成迭代器:坏主意

    构建可迭代的对象和迭代器时经常会出现错误,原因是混淆了二者。

    要知道,可迭代的对象有个 __iter__ 方法,每次都实例化一个新的迭代器;

    而迭代器要实现 __next__ 方法,返回单个元素,此外还要实现__iter__ 方法,返回迭代器本身。
    因此,迭代器可以迭代,但是可迭代的对象不是迭代器。

    迭代器模式可用来:

    访问一个聚合对象的内容而无需暴露它的内部表示
    支持对聚合对象的多种遍历
    为遍历不同的聚合结构提供一个统一的接口(即支持多态迭代)

    为了“支持多种遍历”,必须能从同一个可迭代的实例中获取多个独立的迭代器,而且各个迭代器要能维护自身的内部状态,因此这一模式正确
    的实现方式是,每次调用 iter(my_iterable) 都新建一个独立的迭代器。这就是为什么这个示例需要定义 SentenceIterator 类。

    可迭代的对象一定不能是自身的迭代器。也就是说,可迭代的对象必须实现 __iter__ 方法,但不能实现 __next__ 方法。
    另一方面,迭代器应该一直可以迭代。迭代器的 __iter__ 方法应该返回自身。




  • 相关阅读:
    3.24课堂
    3.23作业
    3.23课堂
    3.20作业
    3.20课堂
    3.19作业
    3.19课堂
    3.18课堂
    3.18作业
    46、表与表的连接
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/12965081.html
Copyright © 2011-2022 走看看