python携程详解_python协程

本文详细介绍了Python协程的概念、优缺点及发展历史。从Python2.5到Python3.9,协程的功能不断进化,包括yield from、async/await关键字的引入。文章还展示了如何使用asyncio模块进行协程并发操作,如create_task、gather方法,并探讨了协程与线程的结合使用。最后,通过非阻塞爬虫的实例展示了协程在提高IO密集型任务效率方面的应用。
摘要由CSDN通过智能技术生成

python协程

协程本质上就是一个线程,不过它是协作式的非抢占式的程序,面向的是IO操作。python有GIL的限制,不能充分利用多线程的实现高并发。进程和线程都是通过cpu的调度实现不同任务的有序执行,协程则要在写代码的时候确定执行顺序。由于协程在一个线程中,所以协程不能阻塞。

优缺点:

无需线程上下文切换的开销

在一个线程中,不需要加锁

无法利用多核资源:协程的本质是单线程,需要和进程配合才能运行在多CPU上

进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序

python协程的发展时间较长:

python2.5 为生成器引用.send()、.throw()、.close()方法

python3.3 为引入yield from,可以接收返回值,可以使用yield from定义协程

Python3.4 加入了asyncio模块

Python3.5 增加async、await关键字,在语法层面的提供支持

python3.7 使用async def + await的方式定义协程

此后asyncio模块更加完善和稳定,对底层的API进行的封装和扩展

python将于 3.10版本中移除 以yield from的方式定义协程 (目前版本是3.9.1)

由于asyncio每个版本都会新增功能,对一些旧的底层的API进行封装,极大地方便的使用者,但正因为此,网上有很多教程使用的接口官方已经不建议直接使用,应该改而使用更加高级的API,所以在这里记录一下如何使用这些API。

简单例子

要点:

使用async def的形式定义

在协程中可以使用await关键字,注意其后跟的是"可等待对象"(协程, 任务 和 Future)

协程不能直接执行,需要在asyncio.run()中执行,也可以跟在await后面

async和await这两个关键字只能在协程中使用

import asyncio

async def foo(name):

await asyncio.sleep(1) # 这是一个不会阻塞的sleep,是一个协程

print(f"name = {name}")

async def main():

# 协程本身就是一个可等待对象

await foo("lczmx") # 执行协程

print("done")

if __name__ == '__main__':

# 使用asyncio.run运行

asyncio.run(main())

asyncio.run(main, *, debug=False)方法就是对run_until_complete进行了封装:

loop = events.new_event_loop()

return loop.run_until_complete(main)

关于可等待对象

可等待对象(awaitable)是能在 await 表达式中使用的对象。可以是 协程 或是具有__await__() 方法的对象。

那么协程是如何成为可等待对象的呢?

collections.abc.Awaitable类,这是为可等待对象提供的类,可被用于 await 表达式中

class Awaitable(metaclass=ABCMeta):

__slots__ = ()

@abstractmethod

def __await__(self):# __await__方法必须返回一个 iterator

yield

@classmethod

def __subclasshook__(cls, C):

if cls is Awaitable:

return _check_methods(C, "__await__")

return NotImplemented

用async def复合语句创建的函数,它返回的是一个Coroutine对象,而Coroutine继承Awaitable。

并发

使用协程进行并发操作

方法一

使用asyncio.create_task(coro)方法,返回一个Task对象,Task类继承Future,在python3.7以下版本中使用as

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值