0

0

Python 对象可哈希性的实现条件

舞夢輝影

舞夢輝影

发布时间:2026-02-17 15:03:31

|

730人浏览过

|

来源于php中文网

原创

TypeError: unhashable type错误本质是对象__hash__返回None或未实现,且自定义了__eq__;内置不可变类型有哈希,可变容器刻意禁用;自定义类可哈希须同时满足:__hash__返回int、__eq__与__hash__基于相同不可变属性计算。

python 对象可哈希性的实现条件

对象为什么报 TypeError: unhashable type

Python 报这个错,本质是对象的 __hash__ 方法返回了 None,或压根没实现,同时 __eq__ 又被自定义过。内置不可变类型(如 strinttuple)默认有稳定哈希值;而可变容器(如 listdictset)直接禁用哈希——不是忘了写,是刻意设计。

常见踩坑场景:

  • 把自定义类实例塞进 set 或当 dict 的 key,但没实现 __hash__
  • 实现了 __eq__ 却没配对实现 __hash__,导致 Python 自动把 __hash__ 设为 None
  • __hash__ 里引用了可变属性(比如某个 list 字段),后续修改该属性后哈希值突变,破坏字典/集合内部结构

让自定义类可哈希:必须同时满足三个条件

缺一不可。只写 __hash__ 不够,只写 __eq__ 更糟。

  • __hash__ 方法必须返回一个整数(int),不能返回 floatstr 或其他类型
  • __eq____hash__ 必须基于同一组属性计算——如果两个实例 __eq__ 返回 True,它们的 __hash__ 值必须完全相等
  • 参与哈希计算的所有属性,在对象生命周期内必须保持不变(即类应设计为“逻辑不可变”);否则哈希表查找会失效

示例:

立即学习Python免费学习笔记(深入)”;

class Point:
    def __init__(self, x, y):
        self._x = x  # 用下划线暗示只读
        self._y = y
<pre class="brush:php;toolbar:false;">@property
def x(self):
    return self._x

@property
def y(self):
    return self._y

def __eq__(self, other):
    if not isinstance(other, Point):
        return False
    return self.x == other.x and self.y == other.y

def __hash__(self):
    return hash((self.x, self.y))  # 元组可哈希,且内容不可变

SCA介绍及应用实例 中文WORD版
SCA介绍及应用实例 中文WORD版

本文档主要讲述的是SCA介绍及应用实例;SCA(Service Component Architecture)是针对SOA提出的一套服务体系构建框架协议,内部既融合了IOC的思想,同时又把面向对象的复用由代码复用上升到了业务模块组件复用,同时将服务接口,实现,部署,调用完全分离,通过配置的形式灵活的组装,绑定。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看

下载

__hash__ 返回 None 的两种典型情况

这不是 bug,是 Python 的显式约束机制。

  • 当你重写了 __eq__ 但没定义 __hash__,Python 会自动把 __hash__ 设为 None——哪怕父类原本有哈希能力(比如继承自 object
  • 显式在 __hash__ 中写 return None,效果一样:实例变成不可哈希对象

验证方式很简单:

print(Point(1, 2).__hash__())  # 输出一个整数  
print(list().__hash__())       # 报 AttributeError  
print({}.__hash__())           # 同样报 AttributeError  

注意:AttributeErrorTypeError: unhashable type 是不同错误层级——前者是没这个方法,后者是方法存在但返回了 None

性能与兼容性:哈希值稳定性比“快”更重要

很多人想优化 __hash__ 计算速度,但真正关键的是稳定性:只要对象逻辑上“相等”,哈希值就必须恒定,且不能依赖外部状态(如时间、全局计数器、随机数)。

  • 避免在 __hash__ 中调用 len()sum() 等可能因副作用改变结果的操作
  • 不要用 id() 当哈希值——它随对象内存地址变化,且不同运行周期不一致,无法用于持久化或跨进程场景
  • 如果对象字段含嵌套可变结构(如 list 字段),要么拒绝哈希,要么转成 tuple 再哈希(前提是确认该 list 真的不会再变)

最常被忽略的一点:哈希逻辑一旦上线,就不能随意改动。哪怕只是调整字段顺序或加个默认值,都可能导致缓存失效、集合查找不到原有 key——因为哈希值变了。

相关文章

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

590

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

105

2025.10.23

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

750

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

572

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

234

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

209

2025.08.29

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

315

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

126

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

44

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 4.3万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号