使用 __hash__ 函数设置包含用户定义的 类
Set contains for user defined classes using __hash__ function
鉴于:
class T:
def __hash__(self):
return 1234
t1 = T()
t2 = T()
my_set = { t1 }
我希望打印以下内容 True
:
print t2 in my_set
这不是应该打印 True
因为 t1
和 t2
具有相同的哈希值。如何使 set
的 in
运算符使用给定的哈希函数?
您需要定义一个 __eq__
方法,因为只有 a is b
或等于 a == b
(除了具有相同的 hash
)的实例才会被识别为相等通过 set
和 dict
:
class T:
def __hash__(self):
return 1234
def __eq__(self, other):
return True
t1 = T()
t2 = T()
my_set = { t1 }
print(t2 in my_set) # True
data model on __hash__
(and the same documentation page for Python 2) 对此进行了解释:
__hash__
Called by built-in function hash()
and for operations on members of hashed collections including set
, frozenset
, and dict. __hash__()
should return an integer. The only required property is that objects which compare equal have the same hash value; it is advised to mix together the hash values of the components of the object that also play a part in comparison of objects by packing them into a tuple and hashing the tuple.
If a class does not define an __eq__()
method it should not define a __hash__()
operation either; if it defines __eq__()
but not __hash__()
, its instances will not be usable as items in hashable collections. If a class defines mutable objects and implements an __eq__()
method, it should not implement __hash__()
, since the implementation of hashable collections requires that a key’s hash value is immutable (if the object’s hash value changes, it will be in the wrong hash bucket).
User-defined classes have __eq__()
and __hash__()
methods by default; with them, all objects compare unequal (except with themselves) and x.__hash__()
returns an appropriate value such that x == y
implies both that x is y and hash(x) == hash(y)
.
(强调我的)
注意:在 Python 2 中,您还可以实现 __cmp__
方法而不是 __eq__
。
在伪代码中,set.__contains__()被x in s
调用时的逻辑大致是:
h = hash(s) # This uses your class's __hash__()
i = h % table_size # This logic is internal to the hash table
if table[i] is empty: return False # Nothing found in the set
if table[i] is x: return True # Identity implies equality
if hash(table[i]) != h: return False # Hash mismatch implies inequality
return table[i] == x # This needs __eq__() in your class
鉴于:
class T:
def __hash__(self):
return 1234
t1 = T()
t2 = T()
my_set = { t1 }
我希望打印以下内容 True
:
print t2 in my_set
这不是应该打印 True
因为 t1
和 t2
具有相同的哈希值。如何使 set
的 in
运算符使用给定的哈希函数?
您需要定义一个 __eq__
方法,因为只有 a is b
或等于 a == b
(除了具有相同的 hash
)的实例才会被识别为相等通过 set
和 dict
:
class T:
def __hash__(self):
return 1234
def __eq__(self, other):
return True
t1 = T()
t2 = T()
my_set = { t1 }
print(t2 in my_set) # True
data model on __hash__
(and the same documentation page for Python 2) 对此进行了解释:
__hash__
Called by built-in function
hash()
and for operations on members of hashed collections includingset
,frozenset
, anddict. __hash__()
should return an integer. The only required property is that objects which compare equal have the same hash value; it is advised to mix together the hash values of the components of the object that also play a part in comparison of objects by packing them into a tuple and hashing the tuple.If a class does not define an
__eq__()
method it should not define a__hash__()
operation either; if it defines__eq__()
but not__hash__()
, its instances will not be usable as items in hashable collections. If a class defines mutable objects and implements an__eq__()
method, it should not implement__hash__()
, since the implementation of hashable collections requires that a key’s hash value is immutable (if the object’s hash value changes, it will be in the wrong hash bucket).User-defined classes have
__eq__()
and__hash__()
methods by default; with them, all objects compare unequal (except with themselves) andx.__hash__()
returns an appropriate value such thatx == y
implies both thatx is y and hash(x) == hash(y)
.
(强调我的)
注意:在 Python 2 中,您还可以实现 __cmp__
方法而不是 __eq__
。
在伪代码中,set.__contains__()被x in s
调用时的逻辑大致是:
h = hash(s) # This uses your class's __hash__()
i = h % table_size # This logic is internal to the hash table
if table[i] is empty: return False # Nothing found in the set
if table[i] is x: return True # Identity implies equality
if hash(table[i]) != h: return False # Hash mismatch implies inequality
return table[i] == x # This needs __eq__() in your class