带有对象 ID 的特殊 Python 字典

问题描述 投票:0回答:2

我想创建一个特殊的字典,使用对象 ID 作为键,如下所示:

class ObjectIdDict(dict):

    def __setitem__(self, key, value):
        super(ObjectIdDict, self).__setitem__(id(key), value)

    def __getitem__(self, key):
        super(ObjectIdDict, self).__getitem__(id(key))

但是如果我运行以下测试,则会收到错误:

class ObjectIdDictTest(unittest.TestCase):
    def test_get_and_set(self):
        dict_to_test = ObjectIdDict()
        class Something:
            def __init__(self):
                self.x = 1
        s = Something()
        dict_to_test[s.x] = "message"
        self.assertEqual(dict_to_test[s.x], "message")     

错误信息:

AssertionError: None != 'message'                   

这里出了什么问题?

背景:

创建如此奇特的字典的原因是我想存储对象的每个字段的验证错误,并希望避免将字段名称作为字符串:

domain_object.errors[domain_object.field1]
,否则将字段名称作为字符串(
domain_object.errors["field1"]
)不利于重构和代码完成。

ΤΖΩΤΖιΟΥ:

我确信你不会得到任何东西 使用 ID。

obj.field1= 1;
  print(id(obj.field1)); obj.field1= 2;
  print(id(obj.field1))

如果我不使用 ID,则键将是变量的“值”,而不是其地址。如果两个字段具有相同的值,这将导致错误: def test_ordinary_dict(self): dict_to_test = {} class Something: def __init__(self): self.x = 1 self.y = 1 # same value as self.x! s = Something() dict_to_test[s.x] = "message for x" dict_to_test[s.y] = "message for y" self.assertEqual(dict_to_test[s.x], "message for x") # fails because dict_to_test[s.x] == dict_to_test[1] what results in: # "message for y"

更改变量值会导致新地址并不重要,因为此后验证结果不再有效。

python inheritance dictionary
2个回答
4
投票
__getitem__

必须返回结果:


def __getitem__(self, key): return super(ObjectIdDict, self).__getitem__(id(key)) #^^^^^

如果没有 
return

,隐式返回值为

None
,因此所有键都为
oiddict[key] is None
    


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.