Mark Ransom在SO中的SO question about hashes上回答:
我想确定的是,我是正确的-即使是非母语人士-所以我希望有人能纠正我的想法,如果我做错了。
假设这个类
class Author(object):
def __init__(self, id, name, age):
self.id = id
self.name = name
self.age = age
def __eq__(self, other):
return self.id==other.id\
and self.name==other.name
def __hash__(self):
return hash(('id', self.id,
'name', self.name))
我知道,
__eq__
允许我将此类的对象与==
运算符进行比较。从Marks答案中,我了解到,即使我的对象peter = Author(1, "Peter", 33)
具有__hash__
,它也不是可哈希的,因为我可能会做类似peter.age = 43
的操作,这意味着它不是不变的。因此,我的Author
类的对象不可哈希,因此不能用作例如字典中的键?我是对的还是看来我需要更多的解释? :-) 最佳答案
如果您保证绝不会在其实例上重置id
或name
,则此类的实例是可哈希的。您无法保证使用"we are all consenting adults here"的Python原则永远不会重置这些属性,但是提供重置__hash__
所依赖的属性的方法将是非常糟糕的样式。
例如,如果您在set_name
实例上提供Author
方法,但没有set_id
,则该类的客户端可以合理地假设__hash__
在id
上仅操作。
如果要向Author
的客户明确表明他们不应重置某些属性,则可以通过在其名称前添加_
来将其标记为私有(private)。然后,如果您仍想使用其公共(public)名称提供(只读)属性访问权限,则可以将其设置为property:
class Author(object):
def __init__(self, id, name, age):
self._id = id
self._name = name
self.age = age # ages tend to change, so mutable
id = property(lambda self: self._id)
name = property(lambda self: self._name)
def __eq__(self, other):
return self.id==other.id\
and self.name==other.name
def __hash__(self):
return hash(('id', self.id,
'name', self.name))
关于python - 关于可散列对象的说明需要说明,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6652878/