python async和await详解
时间: 2023-05-01 07:04:09 浏览: 166
Python中的async和await是异步编程中常用的关键字,它们可以用于定义协程和处理异步操作。async用于定义协程函数,将普通函数转化为异步函数,可以在其中使用异步操作;await则用于等待异步操作的完成,将协程挂起,等待异步操作的结果返回。async和await的使用可以大幅简化异步编程的复杂度,提高代码的可读性和可维护性。
相关问题
python的async/await/yield
### Python 中 `async`、`await` 和 `yield` 关键字详解
#### 1. `async` 定义异步函数
`async` 是用于定义协程的关键字。当一个函数被声明为 `async def` 形式时,它返回的是一个协程对象而不是立即执行的结果。这种设计使得该函数可以包含 `await` 表达式来暂停其自身的执行并等待另一个协程完成。
```python
import asyncio
async def my_coroutine():
print("Start")
await asyncio.sleep(1) # 模拟耗时操作
print("End")
# 运行协程
asyncio.run(my_coroutine())
```
#### 2. `await` 执行异步调用
`await` 只能在由 `async def` 声明的函数内部使用,用来挂起当前协程直到右侧表达式的协程完成,并获取它的结果。这允许编写看起来像同步代码但实际上是非阻塞的操作序列[^1]。
```python
async def fetch_data():
data = await get_remote_resource()
process(data)
async def main():
result = await fetch_data()
asyncio.run(main())
```
#### 3. `yield` 实现生成器与旧版协程
`yield` 主要用于创建迭代器(即生成器),但在早期版本中也被用来支持基于生成器的协程语法。通过 `@asyncio.coroutine` 装饰器配合 `yield from` 来模拟现代的 `await` 功能。不过这种方式已经被弃用了,在新项目里应该优先考虑使用更直观易读的新风格——`async/await`[^3]。
```python
from asyncio import coroutine
@coroutine
def old_style_coro():
value = yield from some_async_operation()
handle_result(value)
```
#### 区别总结
- **适用范围**: `async` 和 `await` 组合专为构建高效的并发应用程序而设;相比之下,虽然 `yield` 同样能做些类似的事情但它主要用于数据流处理场景下的惰性求值。
- **语法规则**: 使用 `async` 函数内的任何地方都可以放置 `await` 语句去等待其他协程结束工作;然而只有在特定上下文中才可合法地运用带有 `yield` 的生成器作为简单的协程替代品。
- **性能表现**: 新型 `async/await` 结构不仅简化了编码逻辑而且提高了程序的整体效率,因为它们更好地集成了底层事件循环机制[^4]。
python asyncio 和await
### Python 中 `asyncio` 库及 `await` 关键字使用教程
#### 一、基础概念介绍
在 Python 的异步编程模型中,`asyncio` 是核心库之一。它提供了编写单线程并发代码所需的工具,基于协程、事件循环、任务和其他原语。
- **协程 (Coroutine)**:由带有 `async def` 声明的函数定义而成的对象。当调用这样的函数时,并不会立即执行其中的内容而是返回一个可以被挂起和恢复运行状态的特殊对象——即协程对象[^3]。
- **事件循环 (Event Loop)**:程序启动后进入的一个无限循环过程,在此期间不断监听并处理各种 I/O 或定时器触发的任务。所有的异步操作都依赖于这个中心化的调度机制来协调各个独立工作的单元之间的协作关系[^1]。
- **Task**:为了更好地管理和跟踪多个正在运行中的协程实例的状态变化情况而引入的概念;可以通过 `asyncio.create_task()` 方法显式地将某个普通的协程封装成具有更高优先级级别的 Task 实体以便更高效地参与竞争资源分配权衡考量之中。
- **Future**:表示尚未完成的工作的结果。它可以用来桥接同步世界与异步世界的鸿沟,允许我们以一种统一的方式处理来自不同源头的数据流或计算结果。不过这部分内容暂时还未完全展开说明。
#### 二、`await` 关键字详解
`await` 主要用于等待另一个可等待对象(如上述提到过的三种类型)结束其工作流程后再继续向下执行后续逻辑分支。需要注意的是只有处于异步上下文中才能合法地运用该语法结构:
```python
import asyncio
async def fetch_data(url):
# 模拟网络请求,这里使用 asyncio.sleep 替代实际 IO 操作
await asyncio.sleep(1) # 此处会暂停当前协程直到睡眠时间到达为止
return f"Data from {url}"
```
这段代码展示了最简单的形式下如何利用 `await` 来实现非阻塞式的延时效果模拟真实场景下的数据获取行为[^2]。
对于包含多条连续性的 `await` 表达式的场合,则遵循先进先出原则逐个解决每一个待办事项之后才会推进至下一步动作:
```python
async def main():
data1 = await fetch_data("https://api.example.com/data1") # 首次遇到 await ,整个方法会被挂起直至左侧表达式求值完毕
print(data1)
data2 = await fetch_data("https://api.example.com/data2") # 类似地再次遭遇第二个 await 节点...
print(data2)
if __name__ == "__main__":
asyncio.run(main())
```
然而这种串行化的设计模式显然不是最优解方案,特别是在面对大量相似性质的小型子任务集合时效率低下难以满足高性能需求的应用环境要求。因此官方推荐采用批量提交策略并通过诸如 `asyncio.gather()` 函数一次性收集所有预期产出项从而达到提高吞吐量的目的:
```python
async def parallel_fetches():
urls = ["https://api.example.com/data{}".format(i) for i in range(1, 4)]
tasks = [fetch_data(url) for url in urls]
results = await asyncio.gather(*tasks) # 并发执行多个异步操作并将最终得到的所有响应打包在一起返回给调用者
for result in results:
print(result)
if __name__ == "__main__":
asyncio.run(parallel_fetches())
```
此外还有其他一些高级特性比如超时控制(`wait_for`)、条件判断(`as_completed`)等可以帮助开发者更加灵活自如地掌控复杂的业务逻辑流转路径。
阅读全文
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20241231044930.png)
![pdf](https://img-home.csdnimg.cn/images/20241231044930.png)
![pdf](https://img-home.csdnimg.cn/images/20241231044930.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![pdf](https://img-home.csdnimg.cn/images/20241231044930.png)
![pdf](https://img-home.csdnimg.cn/images/20241231044930.png)
![pdf](https://img-home.csdnimg.cn/images/20241231044930.png)
![](https://img-home.csdnimg.cn/images/20250102104920.png)