I want to create a special dictionary which uses object IDs as keys, like this:
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))
But if I run the following test, I get an error:
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")
Error message:
AssertionError: None != 'message'
What is wrong here?
Background:
The reason for creating such an exotic dict is that I want to store validation errors for each field of an object and want to avoid field names as strings: domain_object.errors[domain_object.field1] otherwise field names as strings (domain_object.errors["field1"]) would be bad for refactoring and code completion.
ΤΖΩΤΖΙΟΥ:
I'm certain you don't get anything by using IDs.
obj.field1= 1; print(id(obj.field1)); obj.field1= 2; print(id(obj.field1))
If I would not use IDs, the key would be the value of the variable, not its address. This would lead to errors if two fields had the same value:
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"
It is not critical that changing a variables value lead to a new address since the validation result is no longer valid after that.
__getitem__ must return the result:
def __getitem__(self, key):
return super(ObjectIdDict, self).__getitem__(id(key))
#^^^^^
Without a return, the implicit return value is None, and therefore oiddict[key] is None for all keys.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With