当前位置: 首页 > news >正文

Python - functools.partial设置回调函数处理异步任务基本使用

一. 前言

在Python中,回调函数是指在一个函数执行完成后,调用另一个函数的过程。通常情况下,回调函数作为参数传递给原始函数,原始函数在执行完自己的逻辑后,会自动调用回调函数并将结果作为参数传递给它。

二. 回调函数基本使用

以下是在Python中设置回调函数的基本步骤:

  1. 定义回调函数,确定回调函数的参数列表和返回值(如果有)。
  2. 在原始函数中,将回调函数作为参数传递给需要回调的函数。
  3. 在原始函数内部的适当位置调用回调函数,将需要传递的参数传递给它。

例如,假设我们需要设置一个回调函数来处理异步操作的结果,可以按如下方式进行设置:

# 定义回调函数
def callback(result):print('Callback function is called with result: ', result)# 异步函数,需要传入回调函数
def async_function(param1, param2, callback):# 进行异步操作result = param1 + param2# 异步操作完成后调用回调函数callback(result)# 调用异步函数,并传入回调函数
async_function(1, 2, callback)

运行结果
在这里插入图片描述
在上面的代码中,我们先定义了一个回调函数callback,然后在异步函数async_function中将该函数作为参数传递,并在异步操作完成后调用回调函数,将操作结果传递给它。

通常情况下,我们会将回调函数定义为一个可调用对象,也就是实现了__call__方法的类对象。使用这种方式,可以更加灵活地定义回调函数,并且可以把一些状态或上下文信息存储在对象中,在回调函数中使用。

三. 进阶 - 使用functools.partial传递函数

1. functools.partial基本介绍

functools.partial 是 Python 标准库中的一个函数,用来部分应用一个函数(partial application),也就是固定函数的一部分参数,返回一个新的函数。
partial 函数的用法如下:

functools.partial(func, *args, **kwargs)

其中,func 是要部分应用的函数,*args 和 **kwargs 是要固定的参数。

具体来说,partial 函数会返回一个新的函数对象,这个新的函数对象跟原来的函数对象是相似的,但是将部分参数固定下来了,相当于原来的函数变成了一个带有默认参数的函数。我们可以用这个新的函数对象来调用原来的函数,而不必传入那些已经固定的参数。

下面是一个简单的示例代码,演示如何使用 partial 函数:

import functools# 定义一个简单的加法函数
def add(a, b):return a + b# 固定 add 函数的第一个参数
add2 = functools.partial(add, 2)# 调用 add2 函数
print(add2(3))  # 输出:5

在上面的示例代码中,我们定义了一个简单的加法函数 add,然后使用 partial 函数将 add 函数的第一个参数固定为 2,得到一个新的函数对象 add2。接下来,我们使用 add2 函数来计算 2+3 的结果,并将结果输出到控制台。

使用 partial 函数的好处是可以更方便地定义新的函数,避免代码重复。比如,如果我们想定义一个加 3、加 4、加 5 的函数,可以使用 partial 来实现,而不必写多个类似的函数。

add3 = functools.partial(add, 3)
add4 = functools.partial(add, 4)
add5 = functools.partial(add, 5)print(add3(2))  # 输出:5
print(add4(2))  # 输出:6
print(add5(2))  # 输出:7

在上面的示例代码中,使用 partial 函数分别定义了 3 个新的函数 add3、add4、add5,分别将加数固定为 3、4、5,然后使用这些新的函数计算 2+3、2+4、2+5 的结果,并将结果输出到控制台。

2. functools.partial进阶使用示例代码

接下来我们看一个socket连接成功之后调用回调函数的例子:

1. 启动一个socket server服务

import json
import os
import socket
import threading
import time
import sys
import tracebackHOST = '127.0.0.1'  # 服务器IP地址
PORT = 8000  # 服务器端口号
BACKLOG = 5  # 服务器监听队列大小,即最多同时接收多少个客户端连接
RECONNECT_INTERVAL = 5  # 重连间隔,单位:秒def start_server():print(os.getpid())while True:try:# 创建一个 TCP/IP socket 对象server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 绑定服务器 IP 地址和端口号server_socket.bind((HOST, PORT))# 开始监听客户端连接请求server_socket.listen(BACKLOG)print('服务器启动,监听端口:%s' % PORT)while True:# 等待客户端连接print('等待客户端连接...')try:client_socket, client_address = server_socket.accept()threading.Thread(target=send_msg, args=(client_socket, client_address)).start()# send_msg(client_socket, client_address)print(f"Process {threading.current_thread()}: {threading.active_count()} threads")print(f"Total threads: {threading.active_count()}")print('新客户端连接,地址:%s' % str(client_address))# 读取客户端发送的数据data = client_socket.recv(1024)print('Received data:', data.decode())# 向客户端发送数据message = 'Welcome to my server!'client_socket.sendall(message.encode())except Exception as e:print('客户端连接异常,错误信息:%s' % e)finally:# 关闭客户端连接client_socket.close()print('客户端连接已关闭')except Exception as e:print('服务器异常,错误信息:%s' % e)traceback.print_exc()# 关闭服务端 socketserver_socket.close()print('{}s后尝试重连服务器...'.format(RECONNECT_INTERVAL))time.sleep(RECONNECT_INTERVAL)def send_msg(client, addr):try:while 1:time.sleep(1)jsonTemplate = {"Command": "FORWARD_ELEV_INFO","DeviceId": "C0002T","ElevId": 1,}msg2Elev = json.dumps(jsonTemplate).encode() + "\n".encode()client.sendto(msg2Elev, addr)print('send msg to client:{}:{}'.format(addr, msg2Elev))except Exception as e:print('send_msg:{}'.format(e))if __name__ == '__main__':# 启动服务器start_server()

2. 开启一个客户端连接,连接成功后调用回调函数

import functools
import json
import socket
import threading
import time
import tracebackclass TestClient(threading.Thread):def __init__(self, connectHost, connectPort, callbackFunc):threading.Thread.__init__(self, name="TestClient")self.host = connectHostself.port = connectPortself.callbackFunc = callbackFuncself.sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)def run(self):self.connect()while True:try:# 从socket中读取数据# data = self.sck.recv(1024)# print(data)data = self.recv_msg(self.sck)if data is None:time.sleep(1)continueself.callbackFunc(data)except OSError:# An operation was attempted on something that is not a sockettraceback.print_exc()time.sleep(5)# FIXME: if socket is broken, reconnect with the same sck does not work, so create an new one.self.sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.connect()except Exception as e:# TODO: if disconnected, connect ittraceback.print_exc()time.sleep(5)self.connect()def recv_msg(self, sock):try:data = sock.recv(1024)print('recv data:{}'.format(data))return dataexcept Exception as e:print('recv_msg:{}'.format(e))sock.close()time.sleep(0.5)def connect(self):while True:try:self.sck.connect((self.host, self.port))print("connected to Service {}:{}".format(self.host, self.port))breakexcept ConnectionRefusedError:print("service refused or not started? Reconnecting to Service in 5s")time.sleep(5)except Exception as e:print("connect error type->{}".format(type(e)))traceback.print_exc()# FIXME: if other exception, not sure to restart action will work.time.sleep(5)def callbackFunc(a, res):print(a)print('callback msg -- >', res)if __name__ == '__main__':connectHost = '127.0.0.1'connectPort = 8000callbackFunc = callbackFuncelevClient = TestClient(connectHost, connectPort, functools.partial(callbackFunc, 'hello callback'))elevClient.start()

上面的程序定义了一个回调函数callbackFunc,在socket连接完成后将其作为参数传给TestClient类的构造函数,用于处理接收到的消息,通过回调方式处理从服务端发送回来的数据。

运行结果
在这里插入图片描述

以上就是关于python functools.partial设置回调函数处理异步任务基本使用介绍,希望对你有所帮助!

相关文章:

Python - functools.partial设置回调函数处理异步任务基本使用

一. 前言 在Python中,回调函数是指在一个函数执行完成后,调用另一个函数的过程。通常情况下,回调函数作为参数传递给原始函数,原始函数在执行完自己的逻辑后,会自动调用回调函数并将结果作为参数传递给它。 二. 回调…...

phpspreadsheet导出excel自动获得列,数字下标

安装composer require phpoffice/phpspreadsheetuse PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Style\Border;$spreadsheet new Spreadsheet(); $sheet $spreadsheet->getActiveSheet();//从65开&a…...

结算日-洛谷

结算日 - 洛谷 解释&#xff1a; 1.用sum记录贝西走到某位置的累计的总钱&#xff0c;flag标记是否有欠债还不了的情况&#xff08;1为有&#xff09;&#xff0c;ans记录步数。 2.若sum<0&#xff0c;则欠债无法还&#xff0c;flag标记为1&#xff0c;并记录下此刻的位置…...

Android Native Code开发学习(一)环境配置

Android Native Code开发学习&#xff08;一&#xff09; 本教程为native code学习笔记&#xff0c;希望能够帮到有需要的人 我的电脑系统为ubuntu 22.04&#xff0c;当然windows也是可以的&#xff0c;区别不大 环境配置 首先我们新建一个native C项目 然后我们下载NDK和C…...

Python GUI应用程序开发之wxPython使用详解

概要 wxPython是一个强大的跨平台GUI工具包&#xff0c;它使用Python编程语言开发&#xff0c;提供了丰富的控件功能。如果你是一名Python开发者&#xff0c;而且希望创建一个功能齐全的桌面应用程序&#xff0c;那么wxPython是一个值得考虑的选择。 什么是wxPython wxPython…...

【电子学会真题】青少年软件编程(C语言)等级考试试卷(一级) 2021年9月

试卷下载 pdf 格式下载&#xff1a;https://download.csdn.net/download/SHUTIAN2010/88255543 word 格式下载&#xff1a;https://download.csdn.net/download/SHUTIAN2010/88255558 1&#xff0e;计算乘积 一行两个整数a、b&#xff0c;以空格分隔。&#xff08;0&#xff1…...

学习完毕JavaSE的感想

今天&#xff0c;把Java复习完毕了&#xff0c;之前学习的时候&#xff0c;学校里学的总是有限的 &#xff0c;自己上手操作之后才发觉差的很多&#xff0c;部署服务器发现要学操作系统&#xff0c;学完了web基础 &#xff0c;又发现还得学前后端分离vue react这些&#xff0c;…...

FastJson的学习

fastjson是阿里巴巴的开源JSON解析库&#xff0c;它可以解析JSON格式的字符串&#xff0c;支持将Java Bean序列化为JSON字符串&#xff0c;也可以从JSON字符串反序列化到JavaBean。 fastjson是json的序列化和反序列化 一、添加依赖 <dependency><groupId>com.ali…...

python scrapy框架

scrapy概述 Scrapy&#xff0c;Python开发的一个快速、高层次的屏幕抓取和web抓取框架&#xff0c;用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛&#xff0c;可以用于数据挖掘、监测和自动化测试 scrapy安装 pip install scrapy -i https://pypi.tuna.tsinghua…...

滑动窗口系列3-Leetcode134题加油站

在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 给定两个整数数组 gas 和 cost &…...

LOIC(low orbit ion cannon)

前言 重要的话说三遍&#xff1a; 该程序仅用于学习用途&#xff0c;请勿用于非法行为上&#xff01;&#xff01;&#xff01; 该程序仅用于学习用途&#xff0c;请勿用于非法行为上&#xff01;&#xff01;&#xff01; 该程序仅用于学习用途&#xff0c;请勿用于非法行为上…...

从格灵深瞳中报稳定盈利,看AI公司的核心竞争力

2023年过半&#xff0c;人工智能产业话题不断。大模型和AIGC掀起热潮&#xff0c;让众多AI公司开始进入新一轮竞赛。但与此同时&#xff0c;不少AI公司依然处于亏损中&#xff0c;研发投入和商业产出难以实现正循环。如何形成健康的商业模式&#xff0c;仍是一大挑战。 AI公司…...

理解 Databend Cluster key 原理及使用

Databend Cluster Key 是指 Databend 可以按声明的 key 排序存储&#xff0c;主要用于用户对时间响应比较高&#xff0c;同时愿意为这个 cluster key 进行额排序操作的用户。 Databend 只支持一个 Cluster key&#xff0c;Cluster key中可以包含多列及表达式。 基本语法 -- 语…...

C++day3(类、this指针、类中的特殊成员函数)

一、Xmind整理&#xff1a; 二、上课笔记整理&#xff1a; 1.类的应用实例 #include <iostream> using namespace std;class Person { private:string name; public:int age;int high;void set_name(string n); //在类内声明函数void show(){cout << "na…...

Qt中的配置文件:实现个性化应用程序配置与保存加载

一、前言 在现代软件开发中,用户对于应用程序的个性化配置和设置变得越来越重要。为了满足用户需求并提供更好的用户体验,开发人员常常需要实现一种机制,以便在每次启动应用程序时能够记住用户上次的配置。这样用户就可以方便地恢复到他们熟悉的环境,无需重新进行所有设置…...

Navicat激活时出现rsa public key not find错误

Navicat激活时出现rsa public key not find错误 在激活时&#xff0c;先不打开应用&#xff0c;先用管理员身份打开注册机Navicat_Keygen_Patch_v5.6_By_DFoX.exe&#xff0c;Navicat v15——>MySql——>Simplified Chinese——>Patch&#xff0c;执行完这些步骤之后…...

FFmpeg5.0源码阅读——URLContext和URLProtocol

摘要&#xff1a;本文描述FFmpeg中URLContext和URLProtocal的实现。   关键字&#xff1a;URLContext、URLProtocal FFmpeg中URLProtocol是具体的协议的抽象&#xff0c;其中定义了对应协议的抽象&#xff0c;其中包含了具体协议的操作函数指针。而URLContext是对协议操作的抽…...

Qt的输出

目录 基本分类 C风格输出 C风格 可以抑制输出 方法一 方法二 在Qt中进行log输出, 一般不使用c中的printf, 也不是使用C中的cout, Qt框架提供了专门用于日志输出的类, 头文件名为 QDebug。 基本分类 qDebug&#xff1a;调试信息提示 qInfo &#xff1a;输出信息 qWarnin…...

长胜证券:久违普涨再现 大盘回升有望加速

获得利好支撑后&#xff0c;大盘开始继续反弹。 沪指周二一路震动反弹&#xff0c;站上3100点整数关口后继续上攻并打破10日均线限制。深成指同样低开高走&#xff0c;全日体现明显强于沪指。 到收盘&#xff0c;沪指报收3135.89点&#xff0c;上涨1.2%&#xff1b;深成指报收…...

WPF .NET 7.0学习整理(一)

参照文档进行不系统的整理&#xff0c;看到那写到那O.o 依赖属性 DependencyProperty&#xff1a;使用专有字段支持属性的标准模式的替代方法。 DependencyObject&#xff1a;定义了可以注册和拥有依赖属性的基类。 public static readonly DependencyProperty IsSpinningPr…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散

前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说&#xff0c;在叠衣服的过程中&#xff0c;我会带着团队对比各种模型、方法、策略&#xff0c;毕竟针对各个场景始终寻找更优的解决方案&#xff0c;是我个人和我司「七月在线」的职责之一 且个人认为&#xff0c…...

macOS 终端智能代理检测

&#x1f9e0; 终端智能代理检测&#xff1a;自动判断是否需要设置代理访问 GitHub 在开发中&#xff0c;使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新&#xff0c;例如&#xff1a; fatal: unable to access https://github.com/ohmyzsh/oh…...

相关类相关的可视化图像总结

目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系&#xff0c;可直观判断线性相关、非线性相关或无相关关系&#xff0c;点的分布密…...

SQL注入篇-sqlmap的配置和使用

在之前的皮卡丘靶场第五期SQL注入的内容中我们谈到了sqlmap&#xff0c;但是由于很多朋友看不了解命令行格式&#xff0c;所以是纯手动获取数据库信息的 接下来我们就用sqlmap来进行皮卡丘靶场的sql注入学习&#xff0c;链接&#xff1a;https://wwhc.lanzoue.com/ifJY32ybh6vc…...

CVE-2023-25194源码分析与漏洞复现(Kafka JNDI注入)

漏洞概述 漏洞名称&#xff1a;Apache Kafka Connect JNDI注入导致的远程代码执行漏洞 CVE编号&#xff1a;CVE-2023-25194 CVSS评分&#xff1a;8.8 影响版本&#xff1a;Apache Kafka 2.3.0 - 3.3.2 修复版本&#xff1a;≥ 3.4.0 漏洞类型&#xff1a;反序列化导致的远程代…...