我无法理解send
方法。我知道它是用来操作发电机的。但是
语法如下:generator.send(value)
。
我不知怎么搞不懂为什么值应该成为当前yield
表达式的结果。我准备了一个例子:
def gen():
for i in range(10):
X = yield i
if X == 'stop':
break
print("Inside the function " + str(X))
m = gen()
print("1 Outside the function " + str(next(m)) + '\n')
print("2 Outside the function " + str(next(m)) + '\n')
print("3 Outside the function " + str(next(m)) + '\n')
print("4 Outside the function " + str(next(m)) + '\n')
print('\n')
print("Outside the function " + str(m.send(None)) + '\n') # Start generator
print("Outside the function " + str(m.send(77)) + '\n')
print("Outside the function " + str(m.send(88)) + '\n')
#print("Outside the function " + str(m.send('stop')) + '\n')
print("Outside the function " + str(m.send(99)) + '\n')
print("Outside the function " + str(m.send(None)) + '\n')
结果是:
1 Outside the function 0
Inside the function None
2 Outside the function 1
Inside the function None
3 Outside the function 2
Inside the function None
4 Outside the function 3
Inside the function None
Outside the function 4
Inside the function 77
Outside the function 5
Inside the function 88
Outside the function 6
Inside the function 99
Outside the function 7
Inside the function None
Outside the function 8
坦白地说,这让我很吃惊。
yield
语句时,生成器的状态被冻结,并且expression_list
的值返回给next
的调用方。
嗯,好像没发生过。为什么我们可以在gen()
内部执行if
语句和print
函数。X
为什么不同?
好 啊。假设send(77)
将77传输到m
。好吧,yield
表达式变成77。
那么什么是X = yield i
?函数内部的77在外部发生时如何转换为5?不管怎样,你能对这些send
和yield
语句做些评论吗?
最令人困惑的部分应该是这一行
X = yield i
,特别是当您在生成器上调用send()
时。实际上你只需要知道:在词汇层面:
next()
等于send(None)
在解释器级别:
X = yield i
等于下面的行(顺序问题):而且,这两行注释正是我们需要第一次调用
send(None)
的原因,因为生成器将返回i
(yieldi
),然后再将值赋给X
结果
请看上面更简单的代码。
我想导致你困惑的是“x=屈服I”声明, 这个语句并不是说从send()方法中接受的值,该方法被设为i,然后我被设为x。 相反,yield语句将值i返回给生成器,x由send()方法生成。一个语句同时执行两个操作。
当您在生成器中使用
send
和表达式yield
时,您将其视为一个协程;一个单独的执行线程,可以按顺序交错运行,但不能与其调用方并行。当调用方执行
R = m.send(a)
时,它将对象a
放入生成器的输入槽中,将控制权传递给生成器,并等待响应。生成器接收作为X = yield i
结果的对象a
,并运行,直到它碰到另一个yield
表达式,例如Y = yield j
。然后它将j
放入其输出槽,将控制权传输回调用方,并等待它再次恢复。调用者接收j
作为R = m.send(a)
的结果,并一直运行,直到它碰到另一个S = m.send(b)
语句,依此类推。R = next(m)
与R = m.send(None)
一样;它将None
放入生成器的输入槽中,因此如果生成器检查X = yield i
的结果,那么X
将是None
。作为一个隐喻,考虑一个dumb waiter:
当服务生接到顾客的订单时,他们把便笺簿放进哑服务生的房间,然后把便笺簿放进厨房,在舱口等菜:
厨师(一直在舱口旁边等着)拿起订单,准备好菜,把它送到餐厅,然后等待下一个订单:
服务员(一直在舱口等着)把菜拿给顾客,然后拿着另一份订单等回来
因为服务器和厨师在点餐或上菜后都在舱口等候,所以在同一时间只有一个人在做任何事情,也就是说,这个过程是单线程的。双方可以使用正常的控制流程,因为发电机机械(哑服务员)负责交织执行。
相关问题 更多 >
编程相关推荐