首页 > 解决方案 > 执行有界方法时未更新 Python 字典键

问题描述

我正在尝试通过订阅者/模式从 python 对象更新密钥,这是更大代码库的一部分,但我想检查我是否在这里做错了什么。

from dataclasses import dataclass
 
@dataclass
class A:
    a:float=2
    def mod(self,name):
        self.a = name
    def __hash__(self):
        return hash(self.a)
class B:
    x = {}
    def attach(self,object):
        self.x[object]= getattr(object,'mod')

    def dispatch(self):
        for _, val in self.x.items():
            val(3)

执行时

>>>a = A()
>>>b = B()
>>>print(a.a)
>>>b.attach(a)
>>>print(b.x)

正如预期的那样:

{A(a=2): <bound method A.mod of A(a=2)>}
>>>print(b.x[a])
<bound method A.mod of A(a=2)>

然后在执行更新时

>>b.dispatch()
>>print(b.x)
{A(a=3): <bound method A.mod of A(a=3)>}

但是当密钥被验证时:

>>>print(list(b.x.keys())[0] is a)
True

尝试检索方法时

>>>print(b.x.get(a)) 
None

标签: pythondictionaryobjectmethodskey

解决方案


显然问题出在哈希的定义方式上。散列应该尊重一些属性。字典根据链接需要可散列的键

来自官方文档

拥有hash () 意味着类的实例是不可变的。可变性是一个复杂的属性,它取决于程序员的意图、eq () 的存在和行为,以及 dataclass() 装饰器中 eq 和 freeze 标志的值。


推荐阅读