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

探索 Python 字典的奥秘:Future 对象为何能成为字典的键?

本质在于作为字典的key能不能执行hash(key)

问题

import concurrent.futuresdef task(n):return n * n# 创建一个线程池
with concurrent.futures.ThreadPoolExecutor() as executor:# 提交任务并获取 Future 对象future_to_num = {executor.submit(task, i): i for i in range(5)}# 处理 Future 对象for future in concurrent.futures.as_completed(future_to_num):num = future_to_num[future]try:result = future.result()print(f"Task for {num} completed with result: {result}")except Exception as exc:print(f"Task for {num} generated an exception: {exc}")

Task for 1 completed with result: 1
Task for 0 completed with result: 0
Task for 2 completed with result: 4
Task for 3 completed with result: 9
Task for 4 completed with result: 16

Future 对象为何能成为字典的键呢

  • 可哈希性:Future 对象实现了 hash() 方法,通常基于对象的内存地址生成哈希值。这意味着每个 Future 对象都有一个独特的哈希值,像是它们的身份证。

  • 身份不变性:尽管 Future 的状态会改变(比如从“未完成”到“已完成”),但它们的身份(即内存地址)在生命周期内是固定的。这种不变性使得它们可以安全地用作字典的键。

案例

import concurrent.futuresdef task(n):return n * na = []
# 创建一个线程池
with concurrent.futures.ThreadPoolExecutor() as executor:# 提交任务并获取 Future 对象for i in range(5):a.append(executor.submit(task, i))
for s in a:print(id(s), hash(s))

140443755307952 8777734706747
140438647408624 8777415463039
140438647408000 8777415463000
140438728177504 8777420511094
140438745725104 8777421607819

import concurrent.futuresdef task(n):return n * n# 创建一个线程池
with concurrent.futures.ThreadPoolExecutor() as executor:# 提交任务并获取 Future 对象for i in range(5):print(hash(executor.submit(task, i)))

8777420511103
8777421607759
8777415491440
8777415491440
8777421607759

对象销毁与哈希值重用

在 Python 中,当一个对象不再被引用时,垃圾回收机制会将其销毁。此时,内存地址可能会被新创建的对象重用。这就是为什么在快速创建和销毁对象的情况下,可能会看到相同的哈希值。

在你的代码中,Future 对象在每次循环迭代结束后就会被销毁,因为没有其他地方存储对它们的引用。如果你希望在任务完成后继续访问这些 Future 对象,你需要将它们存储在一个列表或其他数据结构中。

总结

Python 字典的强大在于其哈希表实现,而 Future 对象之所以能成为字典的键,是因为它们的可哈希性和身份不变性。即使在内存重用的情况下,Python 也能通过哈希值和相等性检查来确保字典的正确性。

http://www.lryc.cn/news/487678.html

相关文章:

  • 多品牌摄像机视频平台EasyCVR视频融合平台+应急布控球:打造城市安全监控新体系
  • Spark 中 RDD checkpoint 是通过启动两个独立的 Job 完成的。
  • 如何下载TikTok视频没有水印
  • 天童美语:提升孩子的自信心的方法
  • 【网络编程】字节序:大端序和小端序
  • 视频融合×室内定位×数字孪生
  • RK3568平台开发系列讲解(platform虚拟总线驱动篇)注册 platform 驱动
  • Jmeter进阶篇(26)杀掉Tomcat的几种方法
  • Solana 区块链的技术解析及未来展望 #dapp开发#公链搭建
  • SMO算法-核方法支持向量机
  • Java项目实战II基于微信小程序的科创微应用平台(开发文档+数据库+源码)
  • HTTP代理是什么,有什么用?
  • Postman之newman
  • 数据库查询表结构和数据量以及占用空间
  • android 性能分析工具(03)Android Studio Profiler及常见性能图表解读
  • vscode 执行 vue 命令无效/禁止运行
  • C++语言系列-STL容器和算法
  • 【Web前端】Promise的使用
  • TDK推出第二代用于汽车安全应用的6轴IMU
  • 免费S3客户端工具大赏
  • 前端访问后端实现跨域
  • TCP和UDP通信基础
  • 微服务中的技术使用与搭配:如何选择合适的工具构建高效的微服务架构
  • 找出字符串第一个匹配项的下标
  • 面向FWA市场!移远通信高性能5G-A模组RG650V-NA通过北美两大重要运营商认证
  • Matlab实现北方苍鹰优化算法优化随机森林算法模型 (NGO-RF)(附源码)
  • 搭建环境 配置编译运行 mpi-test-suite
  • 夜神模拟器启动报错:虚拟机启动失败 请进行修复 关闭hyper-v
  • 投资策略规划最优决策分析
  • 一篇保姆式虚拟机安装ubantu教程