[Python][迭代器和生成器] 带有额外状态的生成器函数

目的

用一个类来包装一个生成器,并添加新的状态在类中,则该类在拥有生成器特性的同时,又持有一些定制的状态信息。

被实验对象

aaa
bbb
ccc
ddd
python a
python b
eee
fff
ggg
python x

代码示例

该示例中未打印出定制化生成器的内容本身,而是打印出了特定时刻的生成器属性内的信息。lines.history才是这个故事的主角。

from collections import deque
#deque是一种双向的列表,可以在左右两端增加和删除元素
class linehistory:
    def __init__(self, lines, histlen=3):
        self.lines = lines
        self.history = deque(maxlen=histlen)
        #maxlen代表deque的长度,只能装下3个元素,如果超过该限度,则将最先进入的元素删除

    def __iter__(self):
        for lineno, line in enumerate(self.lines, 1):
        #枚举函数,起始索引值为1
            self.history.append((lineno, line))
            #如果是一个普通的生成器,yield就足够了
            #但是在此处我们增加一个history,保存了一个特殊的状态
            yield line
			#完成特殊状态处理后,该对象才会像一个普通生成器一样进行yield
    def clear(self):
        self.history.clear()
        #调用了deque的clear方法

with open("test") as f:
    lines = linehistory(f)
    for line in lines:#遍历lines中的line元素,此时跟history无关
        if 'python' in line:#如果line元素中有python这个字符,则执行以下动作
            for lineno, hline in lines.history:#把当前的history中的数据对(index,line)逐个打印出来
                print('{}:{}'.format(lineno,hline),)
            print('#'*30)

演示结果

数据中出现了3次python字样的元素,因此打印了3组数据,每组数据只有最新增加的3个元素

3:ccc

4:ddd

5:python a

##############################
4:ddd

5:python a

6:python b

##############################
8:fff

9:ggg

10:python x
##############################

猜你喜欢

转载自blog.csdn.net/qq_33868661/article/details/114877693