Suppose I have d = {'dogs': 3}
. Using:
d['cats'] = 2
would create the key 'cats'
and give it the value 2
.
If I really intend to update a dict with a new key and value, I would use d.update(cats=2)
because it feels more explicit.
Having automatic creation of a key feels error prone (especially in larger programs), e.g.:
# I decide to make a change to my dict.
d = {'puppies': 4, 'big_dogs': 2}
# Lots and lots of code.
# ....
def change_my_dogs_to_maximum_room_capacity():
# But I forgot to change this as well and there is no error to inform me.
# Instead a bug was created.
d['dogs'] = 1
Question:
Is there a way to disable the automatic creation of a key that doesn't exist through d[key] = value
, and instead raise a KeyError
?
Everything else should keep working though:
d = new_dict() # Works
d = new_dict(hi=1) # Works
d.update(c=5, x=2) # Works
d.setdefault('9', 'something') # Works
d['a_new_key'] = 1 # Raises KeyError
You could create a child of dict
with a special __setitem__
method that refuses keys that didn't exist when it was initially created:
class StrictDict(dict):
def __setitem__(self, key, value):
if key not in self:
raise KeyError("{} is not a legal key of this StricDict".format(repr(key)))
dict.__setitem__(self, key, value)
x = StrictDict({'puppies': 4, 'big_dogs': 2})
x["puppies"] = 23 #this works
x["dogs"] = 42 #this raises an exception
It's not totally bulletproof (it will allow x.update({"cats": 99})
without complaint, for example), but it prevents the most likely case.
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