带有对象ID的特殊Python dict

时间:2011-05-28 07:46:21

标签: python inheritance dictionary

我想创建一个使用对象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'                   

这里有什么问题?

背景:

创建这样一个奇特的dict的原因是我想为对象的每个字段存储验证错误,并希望避免字段名称为字符串: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"

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

1 个答案:

答案 0 :(得分:4)

__getitem__必须返回结果:

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

如果没有return,则隐式返回值为None,因此所有键都为oiddict[key] is None