一、功能
hash() 函数用于获取一个对象(字符串或者数值等)的哈希值,如下图所示:

二、语法和示例
语法结构如下:
C:\Users\amoxiang>ipython
Python 3.12.8 (tags/v3.12.8:2dc476b, Dec 3 2024, 19:30:04) [MSC v.1942 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.32.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: hash?
Signature: hash(obj, /)
Docstring:
Return the hash value for the given object.
Two objects that compare equal must also have the same hash value, but the
reverse is not necessarily true.
Type: builtin_function_or_method
参数说明:
1.obj: 对象
2.返回值: 返回对象的哈希值
【示例1】使用hash()函数输出不同类型数据的哈希值。代码如下:
# -*- coding: utf-8 -*-
# @Time : 2025-05-01 4:28
# @Author : AmoXiang
# @File : hash_demo.py
# @Software: PyCharm
# @Blog: https://blog.youkuaiyun.com/xw1680
int_val = 100
print(f"The integer hash value is : {hash(int_val)}")
str_val = 'amo'
print(f"The string hash value is : {hash(str_val)}")
flt_val = 24.56
print(f"The float hash value is : {hash(flt_val)}")
tuple_val = (1, 2, 3, 4, 5)
print(f"The tuple hash value is : {hash(tuple_val)}")
class A(object):
pass
a = A()
# 当没有实现__hash__()方法,默认: 类与实例对象都是可哈希的,继承自 object
print(f"The class hash value is : {hash(A)}")
print(f"The instance hash value is : {hash(a)}")
运行结果如下图所示:

注意: hash() 函数可以应用于数字、字符串和对象,不能直接应用于列表和字典。此外,不同时间不同电脑输出的结果可能不同。
【示例2】hash()函数实际上是在调用对象的__hash__()方法,所以任何类都可以重写__hash__()方法。代码如下:
# -*- coding: utf-8 -*-
# @Time : 2025-05-01 4:28
# @Author : AmoXiang
# @File : hash_demo.py
# @Software: PyCharm
# @Blog: https://blog.youkuaiyun.com/xw1680
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __hash__(self):
print('The hash is:')
# 1.哈希值必须是 int 类型,且不可变。
# TypeError: __hash__ method should return an integer
# return None
# 2.实现 __hash__ 时常常将多个字段组合为元组并调用 hash()。
return hash((self.name, self.age)) # 元组
student = Student('Andy', 18)
print(hash(student))
【示例3】禁用哈希随机化。hash()函数求解的哈希值是非确定性的,这是因为Python的字符串hash算法并不是直接遍历字符串每个字符去计算hash,而是会有一个secret prefix和一个secret suffix,可以认为相当于是给字符串加盐后做hash,可以规避一些规律输入的情况。例如,hash_demo.py 文件的代码如下:
print(hash('amo'))
执行2次 python hash_demo.py 命令,结果并不相同,运行结果如下图所示:

可以通过设置环境变量 PYTHONHASHSEED 来禁用随机化。环境变量是 PYTHONHASHSEED,配置为一个正整数( 字符串/对象的哈希值是随机的(安全性考虑) ),将作为随机种子;配置为0( 表示禁用随机哈希,每次启动结果一致(方便测试或调试)),则 secret prefix 和 secret suffix 默认清零。使用如下命令输出哈希值:
# Windows CMD 或 PowerShell
set PYTHONHASHSEED=0
python hash_demo.py
# Linux/macOS
PYTHONHASHSEED=0 python hash_demo.py
运行结果如下图所示:

【示例4】创建可哈希对象。如果一个对象在其生命周期内,其哈希值从未改变(这需要一个__hash__()方法),并且可以与其他对象进行比较(这需要一个__eq__()或__cmp__()方法),那么这个对象就是可哈希的。实例对象默认包含__hash__()和__eq__()方法,所以,默认是可哈希的。下面创建一个类,重写__hash__()和__eq__()方法,代码如下:
# -*- coding: utf-8 -*-
# @Time : 2025-05-01 4:28
# @Author : AmoXiang
# @File : hash_demo.py
# @Software: PyCharm
# @Blog: https://blog.youkuaiyun.com/xw1680
class Foo(object):
def __init__(self, item):
self.item = item
def __eq__(self, other):
print('f' + str(self.item) + '调用了equal函数')
if isinstance(other, self.__class__):
print(self.__dict__)
return self.__dict__ == other.__dict__
else:
return False
def __hash__(self):
print('f' + str(self.item) + '调用了hash函数')
return hash(self.item)
def __repr__(self):
return f'<Foo {self.item}>'
f1 = Foo(1) # 实例化Foo()类
f2 = Foo(2) # 实例化Foo()类
f3 = Foo(3) # 实例化Foo()类
f_set = {f1, f2, f3} # 会调用3次__hash__()函数
print(f_set)
f4 = Foo(4) # 实例化Foo()类
f_set.add(f4) # 加入集合,会调用hash函数
f = Foo(3) # 实例化Foo()类
print(f == f3) # True, f.__eq__(f3)
f_set.add(f) # 加入集合,已经存在实例f3,调用equal函数
print(f_set)
1188

被折叠的 条评论
为什么被折叠?



