目的
用一个类来包装一个生成器,并添加新的状态在类中,则该类在拥有生成器特性的同时,又持有一些定制的状态信息。
被实验对象
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
##############################