前言

许多 Web 应用依赖大量的 I/O (输入/输出) 操作,比如从网站上下载图片、视频等内容;进行网络聊天或者针对后台数据库进行多次查询。数据库查询可能会耗费大量时间,尤其是在该数据库处于高负载或查询很复杂的情况下。 Web 服务器可能需要同时处理数百或数千个请求。

I/O 是指计算机的输入和输出设备,例如键盘、硬盘驱动器,以及最常见的网卡。这些操作等待用户输入或从基于 Web 的 API 检索内容。

Asynchronous IO (async IO) 是一种异步编程设计,并在 Python 3.4 的 asyncio 模块中得到了支持,作为在多线程和多进程之外处理这些高并发工作负载的另一种方法,可以显着提高使用 I/O 操作的应用程序的性能和资源利用率。

什么是同步编程

同步编程,通常来说,大多数编程语言都是子例程调用模型:按照顺序运行代码。在此模型中,下一行代码在前一行代码完成后立即运行,并且一次只完成一个模块。

该模型适用于大部分应用程序。但是,也存在明显的缺点,如果一行代码特别慢怎么办?

在这种情况下,速度慢的代码将导致所有其他代码都将被卡住,直到该行完成。最差的情况下可能导致整个应用程序卡死。可能大多数人在某些软件操作中,一个小小的操作导致整个系统执行不下去,最后只能重启。

什么是异步编程

为了解决同步模型的问题,引入了异步编程的概念,意味着允许同一时刻执行多个任务。

异步编程模型意味着需要长时间运行的任务可以在后台运行,与主应用程序分开。系统可以自由地执行不依赖于该任务的其他工作,而不是阻止所有其他应用程序代码等待该长时间运行的任务完成。然后,一旦长时间运行的任务完成,我们会收到通知它已完成。

asyncio 库允许我们使用异步编程模型运行代码。 这让我们可以一次处理多个 I/O 操作,同时仍然允许我们的应用程序保持响应。

在 Python 3.4 中,asyncio 库中包含了装饰器和生成器 yield from 来定义协程(coroutine)。协程是一种方法,当我们有一个可能长时间运行的任务时可以暂停,然后在该任务完成时恢复。

协程执行完成后返回到调用者有一种新方法:通过 yield 控制。当协程的 yield 执行完成后立即回到了调用点,但是对协程的再次调用不会在起始处再次开始,相反,他们继续从最近停止处继续进行。

如下图所示:

def filter_even(numbers):
    for num in range(numbers):
        if (num % 2 == 0):
            yield num
even_number = filter_even(100)
print(list(even_number))

运行结果:

$ python yielddemo.py 
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]

ayncio 版 Hello 程序

Python 3.5 版中,当关键字 async 和 await 显式添加到语言中时,该语言实现了对协程和异步编程的一流支持。 这种语法在 C# 和 JavaScript 等其他编程语言中很常见,它允许我们使异步代码看起来像是同步运行的。 这使得异步代码易于阅读和理解,因为它看起来像大多数软件工程师熟悉的顺序流程。 asyncio 是一个使用称为单线程事件循环的并发模型以异步方式执行这些协程的库。

利用 async/await 两个定义关键字定义协程,通过 asyncio 提供运行和管理协程的基础:

import asyncio
import time
async def main():
    print(f'{time.ctime()} Hello!')
    await asyncio.sleep(1.0)
    print(f'{time.ctime()} See you again!')
asyncio.run(main())

运行结果:

$ python asynciodemo.py 
Sat Jul  9 23:19:40 2022 Hello!
Sat Jul  9 23:19:41 2022 See you again!

asyncio 提供了一个 run() 函数来执行 async def 函数,然后从那里调用的所有其他协程,如 main() 函数中的 sleep() 函数。asyncio 不是多线程或多进程,而是并行运行代码。

JavaScript 中支持异步执行(浏览器,Nodejs,Electron 等)。在早期版本中,他们只是使用回调功能在异步操作完成后运行其他功能。

如何使用 asyncio

创建协程很简单,与创建普通的 Python 函数没有太大区别。唯一的区别是,我们不是使用 def 关键字,而是 使用 async def 。async 关键字将函数标记为协程,而不是普通的 Python 函数。

import asyncio
import time
def write(msg):
    print(msg, flush=True)
async def say1():
    await asyncio.sleep(1)
    write("Hello from 1")
async def say2():
    await asyncio.sleep(1)
    write("Hello from 2")
write("start")
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(
    say1(),
    say2()
))
write("exit")
loop.close()

运行该代码,可以看到 Hello from 1 运行 1 秒后运行 Hello from 2

$ python asyncoidemo2.py 
start
Hello from 1
Hello from 2
exit

run_until_complete 运行 say() 函数,解释器会逐行执行该函数的内容。当碰到 await 之后,解释器开始异步操作:这个操作为了循环将完成一些内部回调操作,这个回调操作是对开发人员隐藏的。但是现在,say1 开始后,它立即将控制返回到事件循环。所以,它启动异步 sleep 和控制循环,然后循环实际上已经开始启动 say2 函数。

当第一次异步 sleep 运行 1秒后,进入内部回调执行 say1 协程,下一个操作是打印 Hello from 1。打印后,它再次返回到活动循环。同时,从第二次睡眠开始,循环获得了有关完成第二次睡眠的事件。

所以接下来 Hello from 2 打印,然后第二种方法也返回。

run_until_complete(gather(l1,l2,l3)) 将阻止所有 l1,l2,l3 Coroutines:

请注意,7 和 9 事件可能会交换 - 如果您多次运行代码,您可能会注意到 Hello from 1 打印在 Hello from 2 之后。

  • event_loop 事件循环:程序开启一个无限循环,把一些函数注册到事件循环上,当满足事件发生的时候,调用相应的协程函数
  • coroutine 协程:协程对象,指一个使用 async 关键字定义的函数,它的调用不会立即执行函数,而是会返回一个协程对象。协程对象需要注册到事件循环,由事件循环调用。
  • task 任务:一个协程对象就是一个原生可以挂起的函数,任务则是对协程进一步封装,其中包含了任务的各种状态
  • future: 代表将来执行或没有执行的任务的结果。它和 task 上没有本质上的区别
  • async/await 关键字:python3.5 用于定义协程的关键字,async 定义一个协程,await 用于挂起阻塞的异步调用接口。

总结

本文首先介绍了同步编程和异步编程的概念,然后引出了协程的基本概念,写了 asyncio 版的 HelloWorld 程序,最后给出了 Python 中 asyncio 库的简易使用方法。

协程的优势在于多 IO 操作时能够有效提高程序速度,例如某些 HTTP 客户端,例如 aiohttps 调用服务器中就利用上了 asyncio 库。

参考链接:Async IO in Python: A Complete Walkthrough

以上就是Python使用Asyncio进行web编程方法详解的详细内容,更多关于Python Asyncio web编程的资料请关注Devmax其它相关文章!

Python使用Asyncio进行web编程方法详解的更多相关文章

  1. XCode 3.2 Ruby和Python模板

    在xcode3.2下,我的ObjectiveCPython/Ruby项目仍然可以打开更新和编译,但是你无法创建新项目.鉴于xcode3.2中缺少ruby和python的所有痕迹(即创建项目并添加新的ruby/python文件),是否有一种简单的方法可以再次安装模板?我发现了一些关于将它们复制到某个文件夹的信息,但我似乎无法让它工作,我怀疑文件夹的位置已经改变为3.2.解决方法3.2中的应用程序模板

  2. Swift基本使用-函数和闭包(三)

    声明函数和其他脚本语言有相似的地方,比较明显的地方是声明函数的关键字swift也出现了Python中的组元,可以通过一个组元返回多个值。传递可变参数,函数以数组的形式获取参数swift中函数可以嵌套,被嵌套的函数可以访问外部函数的变量。可以通过函数的潜逃来重构过长或者太复杂的函数。

  3. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  4. Swift、Go、Julia与R能否挑战 Python 的王者地位

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 红薯因 Swift 重写开源中国失败,貌似欲改用 Python

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  6. 你没看错:Swift可以直接调用Python函数库

    上周Perfect又推出了新一轮服务器端Swift增强函数库:Perfect-Python。对,你没看错,在服务器端Swift其实可以轻松从其他语种的函数库中直接拿来调用,不需要修改任何内容。以如下python脚本为例:Perfect-Python可以用下列方法封装并调用以上函数,您所需要注意的仅仅是其函数名称以及参数。

  7. Swift中的列表解析

    在Swift中完成这个的最简单的方法是什么?我在寻找类似的东西:从Swift2.x开始,有一些与你的Python样式列表解析相当的东西。(在这个意义上,它更像是Python的xrange。如果你想保持集合懒惰一路通过,只是这样说:与Python中的列表解析语法不同,Swift中的这些操作遵循与其他操作相同的语法。

  8. swift抛出终端的python错误

    每当我尝试启动与python相关的swift时,我都会收到错误.我该如何解决?

  9. 在Android上用Java嵌入Python

    解决方法看看this,它适用于J2SE,你可以尝试在Android上运行.

  10. 在android studio中使用python代码构建android应用程序

    我有一些python代码和它的机器人,我正在寻找一种方法来使用android项目中的那些python代码.有没有办法做到这一点!?解决方法有两种主要工具可供使用,它们彼此不同:>QPython>Kivy使用Kivy,大致相同的代码也可以部署到IOS.

随机推荐

  1. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  2. python数学建模之三大模型与十大常用算法详情

    这篇文章主要介绍了python数学建模之三大模型与十大常用算法详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感想取得小伙伴可以参考一下

  3. Python爬取奶茶店数据分析哪家最好喝以及性价比

    这篇文章主要介绍了用Python告诉你奶茶哪家最好喝性价比最高,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  4. 使用pyinstaller打包.exe文件的详细教程

    PyInstaller是一个跨平台的Python应用打包工具,能够把 Python 脚本及其所在的 Python 解释器打包成可执行文件,下面这篇文章主要给大家介绍了关于使用pyinstaller打包.exe文件的相关资料,需要的朋友可以参考下

  5. 基于Python实现射击小游戏的制作

    这篇文章主要介绍了如何利用Python制作一个自己专属的第一人称射击小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手试一试

  6. Python list append方法之给列表追加元素

    这篇文章主要介绍了Python list append方法如何给列表追加元素,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  7. Pytest+Request+Allure+Jenkins实现接口自动化

    这篇文章介绍了Pytest+Request+Allure+Jenkins实现接口自动化的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. 利用python实现简单的情感分析实例教程

    商品评论挖掘、电影推荐、股市预测……情感分析大有用武之地,下面这篇文章主要给大家介绍了关于利用python实现简单的情感分析的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

  9. 利用Python上传日志并监控告警的方法详解

    这篇文章将详细为大家介绍如何通过阿里云日志服务搭建一套通过Python上传日志、配置日志告警的监控服务,感兴趣的小伙伴可以了解一下

  10. Pycharm中运行程序在Python console中执行,不是直接Run问题

    这篇文章主要介绍了Pycharm中运行程序在Python console中执行,不是直接Run问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

返回
顶部