书中的代码用的应该是 Python3.3 的, 从 Python3.5 开始协程用 async 与 await 代替了 @asyncio.coroutine 与 yield.from
话说 asyncio 与 aiohttp 配合使用, 从书中的教程来看真的非常强大, 以后的并发 io 处理, 协程才是王道了.
18.1 线程与协程对比
- import threading
- import itertools
- import time
- import sys
- class Signal:
- go = True
- def spin(msg, signal):
- write, flush = sys.stdout.write, sys.stdout.flush
- for char in itertools.cycle('|/-\\'):
- status = char + ' ' + msg
- write(status)
- flush()
- write('\x08' * len(status))
- time.sleep(.1)
- if not signal.go:
- break
- write('' * len(status) +'\x08' * len(status))
- def slow_function():
- time.sleep(3)
- return 42
- def supervisor():
- singal = Signal()
- spinner = threading.Thread(target=spin, args=('thinking!', singal))
- print('spinner object:', spinner)
- # spinner 线程开始
- spinner.start()
- # 主线程休眠
- result = slow_function()
- # 给 spinner 线程发送关闭信号
- singal.go = False
- spinner.join()
- return result
- def main():
- result = supervisor()
- print('Answer', result)
- if __name__ == '__main__':
- main()
这个一个多线程的显示脚本, 一共两个线程, 主线程负责显示最后的输出, 开辟的子线程负责显示转圈圈.
- import asyncio
- import itertools
- import sys
- async def spin(msg):
- write, flush = sys.stdout.write, sys.stdout.flush
- for char in itertools.cycle('|/-\\'):
- status = char + ' ' + msg
- write(status)
- flush()
- # 继续回到初始位置
- write('\x08' * len(status))
- try:
- await asyncio.sleep(.1)
- # 捕获错误
- except asyncio.CancelledError:
- break
- write('' * len(status) +'\x08' * len(status))
- async def slow_function():
- await asyncio.sleep(3)
- return 42
- async def supervisor():
- # 把协程包装成为一个 task 任务
- spinner = asyncio.ensure_future(spin('thinking!'))
- # 已经是一个任务返回的还是一个任务
- spinner = asyncio.ensure_future(spinner)
- print('spinner object:', spinner)
- # 激活等待 slow_function 任务, 由于 slow_function 里面有 sleep, 会把控制权, 到时候会把控制权转给 spinnner
- slow_function1 = asyncio.ensure_future(slow_function())
- result = await slow_function1
- # 得到 result, 取消 spinner 任务
- # await asyncio.sleep(5)
- spinner.cancel()
- return result
- def main():
- loop = asyncio.get_event_loop()
- result = loop.run_until_complete(supervisor())
- loop.close()
- print('Answer', result)
- if __name__ == '__main__':
- main()
这是一个协程版本的, 最后的协程 supervisor() 里面一共有两个任务, 通过 await asyncio.sleep() 切换协程的工作.
asyncio.ensure_future(...) 接收的是一个协程, 排定它的运作时间, 排定它的运行时间, 然后返回个 asyncio.Task 实例, 也就是 asyncio.Future 的实例, 因为 Task
是 Future 的子类, 用于包装协程.
task 或者 future 都有. done(), .add_done_callback(....) 和. result() 等方法,
只不过这些方法一般用的比较少, 只要 result=await myfuture(), 其中 await 后面需要回调的参数就是, result 就是 task 的 result.
来源: http://www.bubuko.com/infodetail-3393527.html