Python函数为何以及如何可哈希化? [英] Why and how are Python functions hashable?

查看:128
本文介绍了Python函数为何以及如何可哈希化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在Python中尝试了以下命令:

I recently tried the following commands in Python:

>>> {lambda x: 1: 'a'}
{<function __main__.<lambda>>: 'a'}

>>> def p(x): return 1
>>> {p: 'a'}
{<function __main__.p>: 'a'}

两次dict创建成功均表明lambda和常规函数都是可哈希的. (像{[]: 'a'}这样的东西在TypeError: unhashable type: 'list'上失败了.)

The success of both dict creations indicates that both lambda and regular functions are hashable. (Something like {[]: 'a'} fails with TypeError: unhashable type: 'list').

哈希显然不一定是该函数的ID:

The hash is apparently not necessarily the ID of the function:

>>> m = lambda x: 1
>>> id(m)
140643045241584
>>> hash(m)
8790190327599
>>> m.__hash__()
8790190327599

最后一条命令显示__hash__方法是为lambda显式定义的,即,这不是Python根据该类型计算出来的一些自动的东西.

The last command shows that the __hash__ method is explicitly defined for lambdas, i.e., this is not some automagical thing Python computes based on the type.

使函数可哈希化的动机是什么?作为奖励,一个函数的哈希是什么?

What is the motivation behind making functions hashable? For a bonus, what is the hash of a function?

推荐答案

没什么特别的.如您所见,您是否检查了函数类型的未绑定__hash__方法:

It's nothing special. As you can see if you examine the unbound __hash__ method of the function type:

>>> def f(): pass
...
>>> type(f).__hash__
<slot wrapper '__hash__' of 'object' objects>

of 'object' objects部分意味着它仅从object继承了基于默认身份的__hash__.功能==hash通过标识起作用.对于任何继承object.__hash__的类型,idhash之间的区别是正常的:

the of 'object' objects part means it just inherits the default identity-based __hash__ from object. Function == and hash work by identity. The difference between id and hash is normal for any type that inherits object.__hash__:

>>> x = object()
>>> id(x)
40145072L
>>> hash(x)
2509067


您可能会认为__hash__应该只为不可变对象定义,您几乎是正确的,但是缺少关键细节. __hash__仅应为 ==比较中涉及的所有内容不可变的对象定义.对于==基于身份的对象,将hash也基于身份完全是标准的,因为即使对象是可变的,也无法以改变身份的方式进行可变.具有基于身份的==的文件,模块和其他可变对象均以这种方式运行.


You might think __hash__ is only supposed to be defined for immutable objects, and you'd be almost right, but that's missing a key detail. __hash__ should only be defined for objects where everything involved in == comparisons is immutable. For objects whose == is based on identity, it's completely standard to base hash on identity as well, since even if the objects are mutable, they can't possibly be mutable in a way that would change their identity. Files, modules, and other mutable objects with identity-based == all behave this way.

这篇关于Python函数为何以及如何可哈希化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆