【问题标题】:Python Object as Dict Key using __hash__ for accessPython 对象作为字典键使用 __hash__ 进行访问
【发布时间】:2018-05-06 10:57:52
【问题描述】:

学习这个超级简单的课程:

class Foo():
    def __init__(self, iden):
        self.iden = iden
    def __hash__(self):
        return hash(self.iden)
    def __repr__(self):
        return str(self.iden)

目标是创建类的实例以用作字典键。如果省略__repr__,则键是标准对象地址。对于__repr__,可打印的表示可能是:

f = Foo(1)
g = Foo(2)
d = {f:'a', g:'b'}
print(d)
>>> {1:'a', 2:'b'}

当尝试按键访问字典时,如何使用__repr__(或__str__)表示作为键似乎并不明显。

print(d[1]) 
>>> KeyError

【问题讨论】:

  • 究竟如何利用__str__/__repr__来做what?对象在dict(或set)中的位置仅基于其哈希值。 __repr__ 只影响对象出现的方式,而不影响您引用它的方式。
  • 答案是否定的。正如我所说,repr 仅与对象的显示方式 相关,与您如何引用它无关。
  • @glibdud 以上使用__hash__ 也失败了。 hash(1) == 1,但 d[1] 因密钥错误而失败。
  • 好点。除了散列之外,似乎还考虑了其​​他东西(可能是类型?)。我看看能不能找到参考资料。

标签: python python-3.x dictionary


【解决方案1】:

第一件事:__repr__() 是一个红鲱鱼。它只影响对象的显示方式。这与您尝试做的事情无关。

如果你想让两个单独的对象引用字典中的同一个槽,你需要两件事(reference):

  • 对象必须具有相同的哈希 (hash(obj1) == hash(obj2))。
  • 对象必须比较相等 (obj1 == obj2)。

您的上述实现是前者,但不是后者。您需要添加一个__eq__() 方法(无论如何,当您定义__hash__() 时,documentation 确实需要该方法)。

class Foo():
    def __init__(self, iden):
        self.iden = iden
    def __hash__(self):
        return hash(self.iden)
    def __eq__(self, other):
        return self.iden == other

 

>>> d = {Foo(1) : 'a'}
>>> d[1]
'a'

【讨论】:

    猜你喜欢
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    相关资源
    最近更新 更多