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

一个Python并发编程技巧:future当作字典的key当作中间值构建最终结果

一个Python并发编程技巧:future当作字典的key当作中间值构建最终结果

代码如下

'''
我们现在想要得到一个字典: user_id: user_name
但是 子任务的方法只返回了user_id对应的user_name1、同步构建结果比较容易,在for循环user_id的时候每次拿到结果后直接根据临时的user_id构建即可
2、如果是异步获取的话,这里有一个技巧,就是先构建一个 future 到 user_id 的字典,再在同步等待的时候反向构建最终的结果
'''
import time
import traceback
from functools import wraps
from concurrent.futures import ThreadPoolExecutor, as_completeddef timer(func):"""简易函数执行时间装饰器,仅打印函数名和执行时间(秒)"""@wraps(func)  # 保留原函数的名称等元信息def wrapper(*args, **kwargs):start_time = time.perf_counter()  # 记录开始时间(高精度)result = func(*args, **kwargs)  # 执行被装饰的函数end_time = time.perf_counter()  # 记录结束时间execution_time = end_time - start_time  # 计算耗时# 仅打印函数名和执行时间(保留6位小数)print(f"{func.__name__} 执行时间: {execution_time:.6f} 秒")return resultreturn wrapperdef get_user_name_by_id_delay_work(user_id: str) -> str:'''获取用户名的子任务'''# 模拟耗时time.sleep(0.2)return f'user_name-{user_id}'@timer
def get_user_dict_sync(user_id_list: list[str]) -> dict:'''同步代码'''ret = {}if not user_id_list:return retfor uid in user_id_list:curr_user_name = get_user_name_by_id_delay_work(uid)ret[uid] = curr_user_namereturn ret@timer
def get_user_dict_async(user_id_list: list[str]) -> dict:'''异步代码'''ret = {}if not user_id_list:return retthreading_pool = ThreadPoolExecutor(max_workers=10)# Notice 用于映射 future -> user_id,方便后续匹配结果future_to_uid = {}for uid in user_id_list:future = threading_pool.submit(get_user_name_by_id_delay_work,user_id=uid)# Notice 方便后面构建 user_id: user_name 的映射关系future_to_uid[future] = uid# 等待所有任务完成 收集结果for future in as_completed(future_to_uid):curr_uid = future_to_uid[future]try:# 获取子函数的用户名user_name = future.result()if user_name:ret[curr_uid] = user_nameexcept Exception:print(f'并发查用户名失败! uid: {curr_uid}, 异常: {traceback.format_exc()}')return retif __name__ == '__main__':user_id_list = ['id1', 'id2', 'id3', 'id4', 'id5', 'id6', 'id7']ret_sync = get_user_dict_sync(user_id_list)print('ret_sync:>>> ', ret_sync)'''get_user_dict_sync 执行时间: 1.424339 秒ret_sync:>>>  {'id1': 'user_name-id1', 'id2': 'user_name-id2', 'id3': 'user_name-id3', 'id4': 'user_name-id4', 'id5': 'user_name-id5', 'id6': 'user_name-id6', 'id7': 'user_name-id7'}'''ret_async = get_user_dict_async(user_id_list)print('ret_async:>>> ', ret_async)'''get_user_dict_async 执行时间: 0.207139 秒ret_async:>>>  {'id3': 'user_name-id3', 'id1': 'user_name-id1', 'id2': 'user_name-id2', 'id4': 'user_name-id4', 'id6': 'user_name-id6', 'id7': 'user_name-id7', 'id5': 'user_name-id5'}'''

~~~

 

http://www.zskr.cn/news/727.html

相关文章:

  • 国产DevOps平台Wiki模块能力全景解析:从知识协同到合规部署的关键抉择
  • Gitee Wiki如何重塑软件工厂时代的知识管理体系?
  • 第1章 计算机系统概述
  • 2025年,CRM厂家权威榜单【 TOP 5】
  • Why框架元推理,对本吉奥警告的解析与安全证明
  • Yii-1-1-应用开发即时启动指南-全-
  • 中电金信:AI重构测试体系智能化时代的软件工程新范式
  • DOS系统与Windows系统的区别
  • Android Studio 2025.1.1 安装与配置全流程教学
  • Postgres常用语句
  • 如何在Windows系统上安装Final Cut Pro
  • 【案例+1】HarmonyOS官方模板优秀案例 第7期:金融理财 记账应用
  • BurpSuite 代理原理 和 证书钉扎检测技术
  • java、Kotlin经验
  • 强大的OSINT情报工具:Blackbird用户名与邮箱搜索分析平台
  • MySQL索引
  • 从模糊到超清!Aiarty Image Enhancer 安装与使用教程
  • Google Play更改支付地址
  • 对话式 AI Workshop|零帧起手捏个「 Her」——搭建拥有个人记忆的语音助手
  • Codeforces Round 1048 (Div. 1) A Cake Assignment 题解
  • Linux中的字符设备和块设备详解和应用区别
  • Gitee DevOps:本土化研发效能引擎的崛起与突破
  • 在Docker容器中运行TaichiSLAM
  • 计算机图形学 - 渲染 - stone-stone
  • docker,docker-compose安装 - 小
  • Pickle 发布 Whisper 主动式桌面 AI; 吴恩达:不懂计算机原理,就不可能只靠「Vibe Code」变优秀丨日报
  • 爬楼梯 VS 跳绳
  • pb9新建“数据库”选项卡中文说明
  • 开源中国:构建国产开源新生态,驱动智能研发新时代
  • 第一次作业-自我介绍+软工5问