我来自 Java,即使是可变对象也可以是“可哈希的”。
这些天我玩 Python 3.x 只是为了好玩。
以下是 Python 中 hashable 的定义(来自 Python 术语表)。
hashable
如果一个对象有一个在其生命周期内永不改变的哈希值(它需要一个__hash__()
方法),并且可以与其他对象进行比较(它需要一个__eq__()
方法)。比较相等的可哈希对象必须具有相同的哈希值。
哈希性使得对象可以用作字典键和集合成员,因为这些数据结构在内部使用哈希值。
Python 的所有不可变内置对象都是可哈希的;可变容器(例如列表或字典)则不然。默认情况下,作为用户定义类实例的对象是可散列的。它们的比较都不相等(除了它们自己),它们的哈希值源自它们的id()
.
我读了它,我在想……
仍然......为什么他们没有在 Python 中使可变对象可哈希?例如。使用相同的default对于用户定义的对象的哈希机制,即如上面最后两句所述。
默认情况下,作为用户定义类实例的对象是可散列的。它们的比较都不相等(除了它们自己),它们的哈希值来自它们的 id()。
这感觉有点奇怪......所以用户定义的可变对象是可散列的(通过这个默认的散列机制),但内置的可变对象是不可散列的。这不是让事情变得复杂吗?我不明白它能带来什么好处,有人可以解释一下吗?
在Python中,可变对象can是可散列的,但这通常不是一个好主意,因为一般来说,equality是根据这些可变属性来定义的,这可能会导致各种疯狂的行为。
如果内置可变对象根据身份进行哈希处理,就像用户定义对象的默认哈希机制一样,那么它们的哈希值将与其相等性不一致。那就是绝对地一个问题。然而,用户定义的对象默认情况下会根据身份进行比较和散列,因此情况并没有那么糟糕,尽管这组事务不是很有用。
请注意,如果您实施__eq__
在用户定义的类中,__hash__
被设定为None
, 使班级不可散列的.
因此,来自 Python 3 数据模型文档:
用户定义的类有__eq__()
and __hash__()
方法通过
默认;与它们相比,所有对象都不相等(除了
他们自己)和x.__hash__()
返回一个适当的值,使得x == y
意味着这两者x is y
and hash(x) == hash(y)
.
一个重写的类__eq__()
并且没有定义__hash__()
都会有它的__hash__()
隐式设置为None
。当。。。的时候__hash__()
一个类的方法是None
,当程序尝试检索时,该类的实例将引发适当的 TypeError
它们的哈希值,也将被正确识别为不可哈希
检查时isinstance(obj, collections.abc.Hashable)
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)