/ 2019-05-21
yield from关键字可以直接返回一个生成器
l = ['h','e','l']
dic = {'l':'v1','o':'v2'}
s = 'eva'
def yield_from_gen():
for i in l:
yield i
for j in dic:
yield j
for k in s:
yield k
for item in yield_from_gen():
print(item,end='')
>>>helloeva
l = ['h','e','l']
dic = {'l':'v1','o':'v2'}
s = 'eva'
def yield_from_gen():
yield from l
yield from dic
yield from s
for item in yield_from_gen():
print(item,end='')
>>>helloeva
from itertools import chain
l = ['h','e','l']
dic = {'l':'v1','o':'v2'}
s = 'eva'
def yield_from_gen():
yield from chain(l,dic,s)
for item in yield_from_gen():
print(item,end='')
chain和yield from
利用yield from完成股票的计算,yield from能够完成一个委派生成器的作用,在子生成器和调用者之间建立起一个双向通道。
def son_gen():
avg_num = 0
sum_num = 0
count = 1
while True:
num = yield avg_num
if num:
sum_num += num
avg_num = sum_num/count
count += 1
else:break
return avg_num
def depute_gen(key):
while True:
ret = yield from son_gen()
print(key,ret)
def main():
shares_list= {
'sogou':[6.4,6.5,6.6,6.2,6.1,6.6,6.7],
'alibaba':[181.72,184.58,183.54,180,88,169.88,178.21,189.32],
'美团':[59.7,52.6,47.2,55.4,60.7,66.1,74.0]
}
for key in shares_list:
g = depute_gen(key)
next(g)
for v in shares_list[key]:
g.send(v)
g.send(None)
main()
根据维基百科给出的定义,“协程 是为非抢占式多任务产生子程序的计算机程序组件,协程允许不同入口点在不同位置暂停或开始执行程序”。从技术的角度来说,“协程就是你可以暂停执行的函数”。如果你把它理解成“就像生成器一样”,那么你就想对了。
#基于yield实现异步
import time
def consumer():
'''任务1:接收数据,处理数据'''
while True:
x=yield
def producer():
'''任务2:生产数据'''
g=consumer()
next(g)
for i in range(10000000):
g.send(i)
producer()
import datetime
import heapq # 堆模块
import types
import time
class Task:
def __init__(self, wait_until, coro):
self.coro = coro
self.waiting_until = wait_until
def __eq__(self, other):
return self.waiting_until == other.waiting_until
def __lt__(self, other):
return self.waiting_until < other.waiting_until
class SleepingLoop:
def __init__(self, *coros):
self._new = coros
self._waiting = []
def run_until_complete(self):
for coro in self._new:
wait_for = coro.send(None)
heapq.heappush(self._waiting, Task(wait_for, coro))
while self._waiting:
now = datetime.datetime.now()
task = heapq.heappop(self._waiting)
if now < task.waiting_until:
delta = task.waiting_until - now
time.sleep(delta.total_seconds())
now = datetime.datetime.now()
try:
print('*'*50)
wait_until = task.coro.send(now)
print('-'*50)
heapq.heappush(self._waiting, Task(wait_until, task.coro))
except StopIteration:
pass
def sleep(seconds):
now = datetime.datetime.now()
wait_until = now + datetime.timedelta(seconds=seconds)
print('before yield wait_until')
actual = yield wait_until # 返回一个datetime数据类型的时间
print('after yield wait_until')
return actual - now
def countdown(label, length, *, delay=0):
print(label, 'waiting', delay, 'seconds before starting countdown')
delta = yield from sleep(delay)
print(label, 'starting after waiting', delta)
while length:
print(label, 'T-minus', length)
waited = yield from sleep(1)
length -= 1
print(label, 'lift-off!')
def main():
loop = SleepingLoop(countdown('A', 5), countdown('B', 3, delay=2),
countdown('C', 4, delay=1))
start = datetime.datetime.now()
loop.run_until_complete()
print('Total elapsed time is', datetime.datetime.now() - start)
if __name__ == '__main__':
main()
(0)