SICP读书笔记--第五章:序列与协程

mac2025-11-13  7

前段时间偶然发现了github上有了SCIP in python的翻译版本, 想起来之前还有最后一章没整明白就去看了一波, 收获很大, 在这整理一下

文章目录

迭代器作为类的迭代器yield 协程(coroutine)一个典型的协程示例"生产、过滤和消耗"应用场景分析

迭代器

作为类的迭代器

在python中,迭代器应该有一个更广泛的定义 在书的例子中给了一个典型的迭代器

class Letters(object): def __init__(self): self.current = 'a' def __next__(self): print("__next__called") if self.current > 'd': raise StopIteration #可选项 result = self.current self.current = chr(ord(result)+1) return result def __iter__(self): print("__iter__called") return self 特征: 有 next, __iter__方法的类迭代器被for循环调用时, 会调用__iter__, 之后循环调用__next__ 2.1 此特性意味着可以在__iter__中重置迭代器的状态, 不用每次迭代都要使用新的迭代器

yield

需要区别可迭代对象与迭代器 3.1 如list, tuple等可迭代对象, 其特征是拥有__iter__方法, 没有__next__ 3.2 在__iter__中有yield产出的类也可以作为视为迭代器 3.2.1 yield与__next__的return相当? 3.2.2 如下的类也可以作为迭代对象 # can only run once def all_pairs(s): for item1 in s: for item2 in s: yield (item1, item2) class LetterIterable(object): def __iter__(self): current = 'a' while current <= 'd': yield current current = chr(ord(current)+1)

协程(coroutine)

一个典型的协程示例

函数默认有__next__方法, 调用__next__时其将调用自身并使成为一个协程

def match(pattern): print('Looking for ' + pattern) try: while True: s = (yield) if pattern in s: print(s) except GeneratorExit: print("=== Done ===")

对其性质进行测试

f = match('xx') f('xxyxx') #error f.__next__() f.send('xxbxx') #printed f.send('xbxbx') #no result f.send('xxbxx') #printed f.close()

“生产、过滤和消耗”

producer: 使用send生产数据, 一般就是个生成器 filter:使用(yield)消耗数据, 并用send生产数据 filter本意即为过滤元素, 当然也可以对其进行转化 consumer:使用(yield)消耗数据

为了直观理解, 加入一个用例

def consumer(): print('ready to print') try: while True: line = (yield) print(line + '\t-faustellar') except GeneratorExit: print("=== Done ===") def filter1(next_couroutine, param=None): print('miao started') try: while True: s = (yield) if 'import' in s s.replace('import', '加载') next_couroutine.send(s) except GeneratorExit: print("=== miao Done ===") next_coroutine.close() def producer(fname, next_coroutine): a = open(fname,encoding='utf-8') for line in a: next_coroutine.send(a)

定义完之后进行声明与组装, 注意顺序

step3 = consumer() step3.__next__() step2 = filter1(step3) step2.__next__() producer('runok.py',step2) step2.close() step3.close()

应用场景分析

在用例中, 协程并没有必要, 其就是以下代码的复杂版本:

a = open('runok.py',encoding='utf-8') for line in a: if 'import' in line line.replace('import', '加载') print(line + '\t-faustellar')

结合书中案例, 其将在诸多方面有极大应用:

但在更复杂的场景中, 这种模块化的方法将大大简化代码复用的难度需要通信协作的场合在一些需要mainloop的场合简化(?), 如摄像头, 直播/视频流, 实时行情分析等 之后将在深度学习中试用.0.
最新回复(0)