python基础 -- 协程continue

2018-01-27  本文已影响0人  fada492daf5b

1.协程

利用异步,用最少的资源做最多的事

2. 操作

# 协程coroutine

# yield 生成器
def func():
    while True:
        x = yield
        print('x ==> {}...'.format(x))

g = func()

# g.send('开始吧')
# TypeError: can't send non-None value to a just-started generator
# 原因没有启动生成器

# 启动生成器g
# 程序运行到yield,等待下一次运行
next(g) # 或者g.send(None)
# 发送数据
g.send(1) 
g.send('我的天吶。。。')
g.send(g)
# 没有发送数据,但是仍然在yield处
next(g)
g.send(None)

# 两个函数之间传递数值
def consumer():
    r = ''
    while True:
        n = yield r # 弹出r,返回n
        if not n:
            print('我爱你')
            return
        print('[Consumer] consuming {}...'.format(n))
        r = '200 Ok'

def produce(c):
    c.send(None) 
    n = 0
    while n < 5:
        n = n + 1
        print('[Producer] producing {}...'.format(n))
        r = c.send(n) # 给comsumer发送n
        print('[Producer] consumer return: {}...'.format(r))
    c.close()

c = consumer() # 生成一个生成器
produce(c)

# 利用装饰器开启协程
def deco(func):
    def wrapper(*args, **kwagrs):
        gene = func(*args, **kwagrs)
        next(gene) # 启动
        return gene
    return wrapper

@deco
def coroutine():
    n = 0
    while True:
        print('start coroutine {}...'.format(n))
        r = yield n
        print('ended coroutine {}...\n'.format(n))
        n += 1

c = coroutine()
for i in range(10):
    print(c.send(i))

# yield from
# 调用生成器generator
def copy_corontine():
    print('start yield from...')
    r = yield from coroutine()
    print('ended yield from...')

# for i in copy_corontine():
#     print(i)



# 异步IO
# asyncio
import asyncio

@asyncio.coroutine
def hello():
    print("Hello World!")
    # 异步调用asyncio.sleep(1)
    # asyncio.sleep()也是coroutine
    # yield from 调用generator
    r = yield from asyncio.sleep(1)
    print("Hello again!")

# 获取Eventloop:
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
# loop.close()

# asyncio.wait 分发任务
@asyncio.coroutine
def wget(host):
    print('Wget {}...'.format(host))
    connect = asyncio.open_connection(host, 80)
    reader, writer = yield from connect
    header = 'GET / HTTP/1.0\r\nHost: {}\r\n\r\n'.format(host)
    writer.write(header.encode('utf-8'))
    yield from writer.drain()
    while True:
        line = yield from reader.readline()
        if line == b'\r\n':
            break
        print('{} header > {}'.format(host, 
            line.decode('utf-8').rstrip()))
    writer.close()

# loop = asyncio.get_event_loop()
tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
loop.run_until_complete(asyncio.wait(tasks))
# loop.close()

# async/await替代@asyncio.coroutine/await
# @asyncio.coroutine
# def love_me_as_i_go():
#     print('follow me')
#     r = yield from asyncio.sleep(1)
#     print('forget me')

async def love_me_as_i_go():
    print('follow me')
    r = await asyncio.sleep(1)
    print('forget me')

love = love_me_as_i_go()
loop.run_until_complete(love)
上一篇下一篇

猜你喜欢

热点阅读