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

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

迭代器

作为类的迭代器

在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
  1. 特征: 有 next, __iter__方法的类
  2. 迭代器被for循环调用时, 会调用__iter__, 之后循环调用__next__
    2.1 此特性意味着可以在__iter__中重置迭代器的状态, 不用每次迭代都要使用新的迭代器

yield

  1. 需要区别可迭代对象与迭代器
    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')

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

  1. 但在更复杂的场景中, 这种模块化的方法将大大简化代码复用的难度
  2. 需要通信协作的场合
  3. 在一些需要mainloop的场合简化(?), 如摄像头, 直播/视频流, 实时行情分析等
    之后将在深度学习中试用.0.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值