首页 > 编程语言 >深入探究 Python 异步编程:利用 asyncio 和 aiohttp 构建高效并发应用

深入探究 Python 异步编程:利用 asyncio 和 aiohttp 构建高效并发应用

时间:2023-12-09 15:31:42浏览次数:44  
标签:异步 aiohttp Python await async def asyncio

在现代编程中,异步编程已成为处理高并发和IO密集型任务的重要方式。Python 提供了强大的异步编程支持,包括 asyncio 库和 aiohttp 等框架。本文将深入探讨异步编程的概念,以及在 Python 中如何利用异步框架来实现高效的并发编程。

1. 异步编程概念

异步编程允许程序在等待 IO 操作完成时不被阻塞,而是继续执行其他任务。这种方式允许程序能够高效地处理大量并发任务,提高了系统的吞吐量和响应性。

2. asyncio 库介绍

Python 的 asyncio 库是用于编写异步代码的核心模块。它提供了编写异步代码的工具和方法,并能够管理异步任务的执行。并且提供了 async/await 语法来定义异步函数,以及事件循环来管理异步任务。

  • asyncio 是 Python 标准库中的模块,用于支持异步编程。
  • 它基于事件循环(Event Loop)机制,允许异步执行多个任务而无需线程。

2.1 async/await 语法示例

  • async/await 是 Python 3.5 引入的语法,用于定义异步函数和等待异步任务完成。
  • async 关键字用于定义异步函数,await 用于等待异步任务的结果。
import asyncio

async def example_coroutine():
    await asyncio.sleep(1)
    return "Hello, Async!"

2.2 事件循环(Event Loop)示例

  • 事件循环是 asyncio 的核心概念,负责管理和调度异步任务的执行。
  • 通过事件循环,可以调度任务并处理任务的完成或等待状态。
import asyncio

async def main():
    task = asyncio.create_task(example_coroutine())
    result = await task
    print(result)

asyncio.run(main())

2.3 异步任务

  • 异步任务可以是 asyncio 中的协程函数(coroutine function)。
  • 使用 asyncio.create_task()asyncio.ensure_future() 创建异步任务。
import asyncio

async def greet_async(name):
    await asyncio.sleep(1)
    return f"Hello, {name}!"

async def main():
    result = await greet_async("Alice")
    print(result)

asyncio.run(main())

2.4. asyncio 的优势和应用场景

  • 高并发性: asyncio 可以处理大量并发任务而无需创建大量线程。
  • IO 密集型任务: 适用于处理大量 IO 操作,如网络请求、文件读写等。
  • Web 开发: 能够构建高性能的 Web 服务器和客户端,与框架如 aiohttp 配合,提供异步的 HTTP 请求和响应。

3. aiohttp 框架

aiohttp 是一个基于 asyncio 的 HTTP 客户端/服务器框架。用于构建异步的 HTTP 客户端和服务器。它提供了简单易用的 API,使得编写高性能、可扩展的 Web 应用和处理异步 HTTP 请求变得更加方便。

3.1. aiohttp 的主要特性

  • 基于 asyncio 使用异步 IO 操作,能够充分利用异步编程的优势,处理大量并发请求。
  • 支持 HTTP 客户端和服务器: 可用于构建异步的 Web 服务器和客户端。
  • WebSocket 支持: 提供了 WebSocket 客户端和服务器,用于实现实时通信。
  • 中间件和拦截器: 支持中间件,可以在请求/响应处理之前或之后执行一些操作。
  • SSL/TLS 支持: 提供对加密通信的支持,保障数据安全。

3.2 使用 aiohttp 构建 HTTP 客户端

3.2.1 发送 GET 请求

import aiohttp
import asyncio

async def fetch_data(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    url = "https://jsonplaceholder.typicode.com/posts/1"
    result = await fetch_data(url)
    print(result)

asyncio.run(main())

3.2.2 发送 POST请求

import aiohttp
import asyncio

async def send_data(url, data):
    async with aiohttp.ClientSession() as session:
        async with session.post(url, json=data) as response:
            return await response.text()

async def main():
    url = "https://jsonplaceholder.typicode.com/posts"
    data = {'title': 'Example', 'body': 'Content'}
    result = await send_data(url, data)
    print(result)

asyncio.run(main())

3.3 构建 HTTP 服务器

3.3.1 创建简单的 HTTP 服务器

from aiohttp import web

async def handle(request):
    return web.Response(text="Hello, aiohttp!")

app = web.Application()
app.router.add_get('/', handle)

if __name__ == '__main__':
    web.run_app(app)

3.3.2 添加路由和视图

from aiohttp import web

async def hello(request):
    return web.Response(text="Hello, World!")

async def greet(request):
    name = request.match_info.get('name', 'Anonymous')
    return web.Response(text=f"Hello, {name}!")

app = web.Application()
app.router.add_get('/', hello)
app.router.add_get('/greet/{name}', greet)

if __name__ == '__main__':
    web.run_app(app)

3.4. aiohttp 的应用场景

  • Web 开发: 构建高性能、异步的 Web 服务器和客户端。
  • API 开发: 提供异步的 API 服务,处理大量请求。
  • 实时通信: 使用 WebSocket 实现实时通信功能。

4. 并发任务管理

异步编程的优势在于能够处理大量并发任务。以下是异步编程中并发任务管理的一些关键概念和技巧:

4.1 并发任务池asyncio.gather()

  • asyncio.gather() 用于同时运行多个协程,并等待它们全部完成。
  • 它接受一组协程作为参数,将它们提交到事件循环中执行,并在所有协程完成后返回结果。
import asyncio

async def worker(task_id):
    await asyncio.sleep(1)
    print(f"Task {task_id} completed")

async def main():
    tasks = [worker(i) for i in range(5)]
    results = await asyncio.gather(*tasks)
    print(results)

asyncio.run(main())

4.2. asyncio.create_task()

  • asyncio.create_task() 用于将单个协程转换为一个任务对象,可并发执行多个任务。
  • 它将协程封装成任务对象,使其能够交给事件循环处理。
import asyncio

async def worker(task_id):
    await asyncio.sleep(1)
    return f"Task {task_id} completed"

async def main():
    task1 = asyncio.create_task(worker(1))
    task2 = asyncio.create_task(worker(2))
    await asyncio.gather(task1, task2)
    print(task1.result(), task2.result())

asyncio.run(main())

4.3. asyncio.ensure_future()

  • asyncio.ensure_future() 将一个协程对象包装成一个任务对象。
  • 这个方法不推荐在 Python 3.7 及以上版本中使用,因为它在 Python 3.7 中已经被标记为过时。
import asyncio

async def worker(task_id):
    await asyncio.sleep(1)
    return f"Task {task_id} completed"

async def main():
    task1 = asyncio.ensure_future(worker(1))
    task2 = asyncio.ensure_future(worker(2))
    await asyncio.gather(task1, task2)
    print(task1.result(), task2.result())

asyncio.run(main())

4.4 异步文件操作

import asyncio

async def read_file(file_path):
    async with aiofiles.open(file_path, mode='r') as file:
        contents = await file.read()
        print(contents)

asyncio.run(read_file('example.txt'))

通过这些方法,可以方便地管理多个并发任务的执行,从而提高程序的效率和性能。异步框架 asyncio 提供了这些工具来简化并发任务的处理,使得异步编程变得更加高效和灵活。

结论

asyncio 能够使 Python 处理并发和异步任务变得更加简单和高效。它提供了一种非阻塞、基于事件的异步编程方式,适用于各种类型的应用和任务。

aiohttp 是一个强大且灵活的异步 HTTP 框架,适用于构建高性能的 Web 应用和处理异步 HTTP 请求。它允许开发者使用异步编程的优势来处理并发请求,提高了系统的性能和响应速度。

Python 的异步编程和并发性为处理高并发和IO密集型任务提供了强大的支持。通过 asyncio 和 aiohttp 等库,开发人员能够轻松地实现高效的异步编程,提高程序的性能和响应速度。

标签:异步,aiohttp,Python,await,async,def,asyncio
From: https://blog.51cto.com/u_16170163/8750056

相关文章

  • python+sklearn 机器学习代码备忘
    importsklearnfromsklearn.model_selectionimporttrain_test_splitfromsklearn.linear_modelimportLinearRegressionimportpandasaspdimportmatplotlib.pyplotaspltimportseabornassnsfromsklearnimportpreprocessingimportcsvimportnumpyas......
  • Python 变量类型
    变量是存储在内存中的值,这就意味着在创建变量时会在内存中开辟一个空间。基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中。因此,变量可以指定不同的数据类型,这些变量可以存储整数,小数或字符。变量赋值Python中的变量赋值不需要类型声明。每个变量在内存......
  • Python算法——快速排序
    快速排序(QuickSort)是一种高效的分治排序算法,它选择一个基准元素,将数组分成两个子数组,小于基准的放在左边,大于基准的放在右边,然后递归地排序子数组。快速排序通常比冒泡排序和选择排序更高效,特别适用于大型数据集。本文将详细介绍快速排序的工作原理和Python实现。快速排序的工作原......
  • Python:函数综合案例-黑马ATM
    综合案例:黑马ATM主菜单查询余额效果存取款效果#总额totaltotal=5000000#定义None影响不大,可以不定义name=None#要求客户输入姓名name=input("请输入您姓名:")#菜单提示defmenu():print("-"*19+"主菜单"+"-"*19)print(f"{name},您......
  • Python:数据容器-list(列表)
    列表定义语法:字面量[元素1,元素2,元素3,...]定义变量变量名称=[元素1,元素2,元素3,...]定义空列表变量名称=[]变量名称=list()列表内的每个数据,称之为元素以[]作为标识列表内每个元素用,逗号隔开注意事项:列表可以一次多个数据,且可以为不同数据类型,支持嵌套"......
  • Python:列表的下标索引
    列表的下标(索引):取出特定位置的数据语法:列表[下标索引]列表的下标(索引)-反向反向索引就是从后向前:从-1开始,依次递减(-1、-2、-3...)嵌套列表的下标(索引)列表[内层列表[索引]]#通过下标索引取出对应位置的数据my_list=["itheima",666,True]#列表[下标索引],从前向后从......
  • Python:列表的常用操作方法
    列表上限:2**63、922372036854775807个查询元素查找指定元素在列表的下标,如果找不到,报错ValueError语法:列表.index(元素)插入元素在指定下标位置,插入指定的元素语法:列表.insert(下标,元素)追加元素将指定元素,追加到列表的尾部语法:列表.append(元素)将其他数据容器的内容......
  • Python:列表的循环遍历
    while循环遍历for循环遍历#列表的遍历-while循环遍历deflist_while_func():"""列表的遍历-while循环遍历:return:None"""list1=[21,25,21,23,22,20]index=0whileindex<len(list1):tmp=list1[ind......
  • Python:元组的定义和操作
    1、元组的定义语法:定义元组使用小括号,且使用逗号隔开各个数据元组面量(元素1,元素2,元素3,...)定义元组变量变量名称=(元素1,元素2,元素3,...)定义空元组变量名称=()变量名称=tuple()2、元组的特点元组同列表一样,可以存储多个、不同的数据类的元素(混装)元组一旦定义完......
  • Python中函数的基础定义语法
    1、函数的定义语法:def函数名(传入参数):函数体return返回值2、函数的调用:函数名(参数)3、函数使用步骤:先定义函数后调用函数4、注意事项:参数不需要,可以省略返回值如不需要,可以省略函数必须先定义后使用#定义一个函数,输出相关信息defsay_hi():......