Python 常用内置函数详解(六):hash()函数----用于获取一个对象(字符串或者数值等)的哈希值

该文章已生成可运行项目,

一、功能

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)
本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

棒棒编程修炼场

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值