迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Python >

Python 中的 Promise 系列

作者:迹忆客 最近更新:2023/06/19 浏览次数:

本篇文章将介绍如何用 Python 编写一系列 promise。 首先,我们将讨论 Python 中的异步编程。

接下来,我们将讨论 Python 中的回调函数。 最后,在进入实际主题之前,我们将简要讨论 Python 中的 try/except,然后讨论 Python 中的一系列 Promise。


Python 中的异步编程

本文希望您对操作系统线程有基本的了解。 如果对线程没有初步的了解,可以先阅读操作系统中的线程。

异步编程允许多个线程并行运行,而主程序(通常称为主/管理线程)可以创建多个工作线程。 通常,主线程等待工作线程,工作线程在完成任务后通知主线程。

与常规编程不同,异步函数暂停并允许并行运行其他函数(线程),而不是在竞争之前保持控制。

我们将讨论并给出一个 Python 异步编程的例子; 不过,最好先看看相关的同步代码。 此代码将有助于通过比较来加深理解。

def count():
    for i in range(5):
        print(i, end=' ')

def main():
    count()
    count()
    count()

main()

在这里,我们依次调用了 3 次 count 函数。 输出符合预期。

0 1 2 3 4 0 1 2 3 4 0 1 2 3 4

可以看到第一个计数函数的输出,接着是第二次调用计数函数的输出,最后是最后一个计数函数的输出。

Python 的 asyncio 库允许在 Python 中运行异步程序。 异步编程的第一个要求是将函数设计为可等待对象。

将标准函数转换为可等待对象有两个要求。 第一种是使用 async 关键字(在 def 关键字之前)创建异步函数而不是常规函数。

第二个需求是在异步函数内部调用sleep函数,挂起当前函数,控制其他函数。

sleep 语句是代码中函数准确进入挂起状态的特定点。 异步编程的第二个需求是在调用可等待对象(异步函数)的同时加入await; 否则会出错。

await 关键字告诉事件循环暂停当前函数,以便为其他函数提供运行时间。

第三个需求是调用 gather 函数并传递 awaitable 对象(异步函数)。 gather 函数按顺序但同时运行这些函数。

这意味着第一个函数首先启动,一段时间后,第二个函数也并行启动。 类似地,所有异步函数开始并发运行,一个接一个。

现在,让我们看看代码。

import asyncio

async def count():
    for i in range(5):
        print(i, end=' ')
        await asyncio.sleep(0.5)

async def main():
    await asyncio.gather(count(), count(), count())

if __name__ == "__main__":

    asyncio.run(main())

在这里,我们将之前的代码转换为异步代码并添加了某些内容。 在第一行中,导入了 asyncio 库。

async 关键字添加在所有函数的开头。

睡眠函数调用被添加到计数函数中。 await 关键字被添加到所有函数调用中,包括 main 函数。

最后,在 main 中调用 gather 函数,其中多次调用 count 函数以将每个函数调用作为一个单独的线程进行演示。

使用 gather 函数,我们添加可等待对象以形成一组异步函数并发运行。 让我们看看这段代码的输出。

0 0 0 1 1 1 2 2 2 3 3 3 4 4 4

在输出中,您可以看到所有线程并行运行并产生异步输出,而不是一起运行。

您可能会混淆多次调用同一个函数; 这是另一个例子,我们有不同的功能并行运行。

import asyncio

async def count1():
    for i in range(10):
        print(i, end=' ')
        await asyncio.sleep(0.5)

async def count2():
    for i in range(50,60):
        print(i, end=' ')
        await asyncio.sleep(0.5)

async def main():
    await asyncio.gather(count1(), count2())

asyncio.run(main())

此代码的输出是:

0 50 1 51 2 52 3 53 4 54 5 55 6 56 7 57 8 58 9 59

同样,这两个函数同时运行。


回调函数

回调被传递给另一个函数(作为参数)。 另一个函数应该在其定义的某处回调此函数。

但是,调用点取决于另一个函数的定义方式。

在这里,我们有一个与回调函数相关的简单编码示例。

import random as r

def callback1(s):
    print(f'******* {s} *******')

def callback2(s):
    print(f'^^^^^^^ {s} ^^^^^^^')

def print_through_callback(message, f1, f2):
    if r.randint(0,1) == 0:
        f1(message)
    else:
        f2(message)

def main():

    print_through_callback("Callback Example", callback1, callback2)

main()

在这段代码中,我们的打印函数有三个参数。 第二个和第三个参数是一些函数名。

大体上,我们传递两个函数,代码随机调用一个。 如果多次运行此代码,您会看到这两个函数都是随机调用的。


在 Python 中try/except

Python 还提供异常处理。 在 Python 中,我们有一个 try 块来测试代码; 它有可能发生异常,在 except 块中,您可以处理异常。

我们都知道除以零是没有定义的,程序(几乎所有编程语言)都会崩溃; 当我们调用除以零操作时。 如果您不知道,请尝试此代码。

def main():
        x = int(input('Enter any number:'))
        print (2/x)
main()

输入零,看结果; 你的程序会崩溃。 代码崩溃是一件坏事,应该通过异常处理来避免。

查看异常处理的相同代码。

def main():
    try:
        x = int(input('Enter any number:'))
        print (2/x)
    except:
        print ('Divide by zero is not defined')

main()

您应该运行此代码并输入非零值; 你会得到除法运算的结果,写在 print (2/x) 里面; 如果您输入零,程序将给出消息除以零未定义而不是崩溃。


Python 中的 Promise 系列

回调函数与普通函数相同; 但是,它们的用途不同。

考虑需要大量时间执行的重量级函数。 通常,这些函数是异步的。

异步函数将在后台执行,并在特定时间后完成,而其他函数将并行启动。 但是,如果你想在完成一些重量级的功能后运行一些功能,选择是使用回调函数。

但是,完成此类任务存在问题。 如果任务在完成之前抛出异常怎么办?

为了确保在成功完成任务后调用该函数,需要承诺和异步编程。

Promises

promise 是一个对象,表示异步函数的成功或不成功(失败)完成。

Promise 对象还表示异步函数的结果值。 Promise 用于管理与多个回调相关的问题。

我们可以使用 promise API 在 Python 中执行一系列的 promise。 然而,我们可以通过 async/await 在 Python 中达到同样的目的。

要在 Python 中使用异步函数实现,我们必须使用带有异步函数的 asyncio 库。 我们可以使用上面已经描述的 await 关键字顺序调用函数。

最后,我们使用 try/except 块。 首先,查看代码和输出。

稍后,我们将解释 try/except 块的用途。

import asyncio
import random as r

async def f1(x):
    await asyncio.sleep(1)
    return x ** 2

async def f2(x):
    await asyncio.sleep(1)
    return x / 2

async def f3(x):
    if r.randint(0, 1) == 0:
        return x
    raise ValueError(x)

async def run():
    try:
        value = await f3(await f2(await f1(r.randint(5,9))))
    except ValueError as exception:
        print('Exception Occurred:', exception.args[0])
    else:
        print('No Exception:', value)

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())
    loop.close()

以下是上述 Python 脚本 5 次运行的组合输出。

No Exception: 12.5
Exception Occurred: 12.5
Exception Occurred: 32.0
No Exception: 18.0
No Exception: 40.5

输出只是描述我们在某些异步操作中可能成功或失败。 因此,我们可以在 try 块中的函数调用之后放置一个回调函数的语句。

如果成功完成,代码将执行回调函数。 失败时,控件将转到 except 块并忽略回调函数。

这样,我们就可以处理Python中的 promises 系列了; 如果我们成功完成,则执行回调函数(这取决于某些所需任务的成功完成); 否则,我们不必执行我们的回调函数。

上一篇:Python 中的队优先级列比较器

下一篇:没有了

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Python 中的队优先级列比较器

发布时间:2023/06/19 浏览次数:192 分类:Python

本文将研究使用 Python 开发自定义优先级队列。 除此之外,我们还将学习如何将自定义比较器函数与优先级队列一起使用。Python 中的优先级队列

为 Python 创建别名

发布时间:2023/06/19 浏览次数:194 分类:Python

在这种情况下,您决定保留两个版本的 Python。 在本文中,我们将学习如何在拥有两个 Python 版本的情况下创建别名。为 Python 创建别名

从 Python 使用 DLL 文件

发布时间:2023/06/19 浏览次数:60 分类:Python

本篇文章将介绍使用 Python 程序中的 DLL 文件。使用 ctypes 库从 Python 使用 DLL 文件 ctypes 是一个在 Python 中提供与 C 兼容的数据类型的外部函数库。

在 Python 中将数据类转换为 JSON

发布时间:2023/06/19 浏览次数:63 分类:Python

在本篇文章中,我们将了解 Python 如何支持 JSON 来为每个 JSON 根节点创建数据类。 我们还将学习 dataclass 作为 Python 字典的实现。在 Python 中将数据类转换为 JSON

Python Dict 与 Asdict

发布时间:2023/06/19 浏览次数:177 分类:Python

obj._dict_() 背后的概述至少比 dataclasses.asdict(obj) 快十倍。Python 3.7引入了dataclasses库,让我们可以制作专门用于数据存储的结构化类。

在 Qt Creator 中开发 Python 应用程序

发布时间:2023/06/19 浏览次数:60 分类:Python

Qt Creator 是一个跨平台的 IDE,可让您为桌面、嵌入式和移动设备创建软件。 它在 Linux、macOS 和 Windows 操作系统上运行。本篇文章将介绍使用 Qt Creator 应用程序开发 Python 应用程序。

Python if-else 速记

发布时间:2023/06/19 浏览次数:72 分类:Python

本文解释了 Python 中 if-else 语句的简写表示法,它使用条件、正值和负值作为其组成部分。

Python 地址解析器

发布时间:2023/06/19 浏览次数:101 分类:Python

本文将向您展示如何使用 Python 解析地址。 我们将使用 pyparsing 库手动解析地址,并使用函数或 pyparsing 获取 CSV 文件中的地址。

使用 Python 列出串口

发布时间:2023/06/19 浏览次数:53 分类:Python

在本文中,我们将讨论使用串口或 com 端口的通信。 我们将深入探索 Python 包,以帮助我们获得系统的可用通信端口。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便