python 的异步写法
时间: 2024-11-13 21:23:23 浏览: 17
Python中异步编程通常用于处理IO密集型任务,比如网络请求、文件读写等,可以显著提高程序的并发性能。Python通过多种库支持异步编程,其中最常用的是`asyncio`模块以及第三方库如`aiohttp`、`协程装饰器`等。
`asyncio`的核心是`async`和`await`关键字。`async`关键字前的函数称为协程(coroutine),它们可以在运行过程中挂起并让出控制权给其他协程执行,直到被`await`后面的异步操作完成。例如:
```python
import asyncio
async def fetch_data(url):
# 模拟耗时的网络请求
await asyncio.sleep(1)
return "Data from " + url
async def main():
loop = asyncio.get_event_loop()
response = await fetch_data('https://example.com')
print(response)
# 运行主协程
asyncio.run(main())
```
在这个例子中,`fetch_data`函数会异步地等待网络请求完成,然后返回结果。
此外,`asyncio.gather()`和`asyncio.wait()`等函数可以帮助组织和管理多个协程的并发执行。
相关问题
python3.9异步爬虫的写法
Python 3.9 引入了一些新的异步编程特性,例如 `async with` 和 `async for`,可以更方便地编写异步爬虫。下面是一个简单的 Python 3.9 异步爬虫示例:
```python
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
async with aiohttp.ClientSession() as session:
html = await fetch(session, 'https://www.example.com')
print(html)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
```
在这个示例中,我们使用了 `async with` 来创建了一个 `aiohttp` 的异步客户端会话(`ClientSession`),然后使用 `async with` 发起了一个 GET 请求,获取了页面的 HTML 内容。最后,我们使用 `asyncio` 的事件循环来运行 `main()` 函数,获取爬取结果。
这个示例中只爬取了一个页面,如果需要爬取多个页面,可以使用 `asyncio.gather()` 函数来并发发起多个请求,提高爬取效率。
import asyncio import time async def func1(): print('这是aaa') await asyncio.sleep(3) print('这是aaa') async def func2(): print('这是bbb') await asyncio.sleep(2) print('这是bbb') async def func3(): print('这是ccc') await asyncio.sleep(4) print('这是ccc') if __name__ == '__main__': f1 = func1() f2 = func2() f3 = func3() tasks = [f1, f2, f3] t1 = time.time() asyncio.run(asyncio.wait(tasks)) t2 = time.time() print(t2-t1) 请问我的Python是目前官方最新版本,为什么我这种异步写法的代码会报错, 错误为TypeError: Passing coroutines is forbidden, use tasks explicitly.
这是因为最新版的Python已经不允许直接将协程对象传递给asyncio.wait()函数,需要将协程对象转换成任务对象。可以使用asyncio.create_task()函数将协程对象转换成任务对象,然后将任务对象加入到任务列表中即可。修改后的代码如下:
```python
import asyncio
import time
async def func1():
print('这是aaa')
await asyncio.sleep(3)
print('这是aaa')
async def func2():
print('这是bbb')
await asyncio.sleep(2)
print('这是bbb')
async def func3():
print('这是ccc')
await asyncio.sleep(4)
print('这是ccc')
if __name__ == '__main__':
f1 = asyncio.create_task(func1())
f2 = asyncio.create_task(func2())
f3 = asyncio.create_task(func3())
tasks = [f1, f2, f3]
t1 = time.time()
asyncio.run(asyncio.wait(tasks))
t2 = time.time()
print(t2-t1)
```
这样就可以正常运行了。
阅读全文