Python函数为何以及如何可哈希化? [英] Why and how are Python functions hashable?
问题描述
我最近在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 lambda
s, 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__
的类型,id
和hash
之间的区别是正常的:
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屋!