missing handles KeyError when accessing missing dictionary keys.
1class DefaultDict(dict):2 def __missing__(self, key):3 self[key] = f"default_{key}"4 return self[key]56d = DefaultDict()7print(d["existing"]) # KeyError (not in dict)89d["name"] = "Alice"10print(d["name"]) # "Alice"11print(d["missing"]) # "default_missing"12print(d) # {"name": "Alice", "missing": "default_missing"}1314# Counter-like implementation15from collections import Counter1617class AutoCounter(dict):18 def __missing__(self, key):19 return 02021counter = AutoCounter()22counter["a"] += 1 # Works! 0 + 1 = 123counter["b"] += 524print(counter) # {"a": 1, "b": 5}2526# Cached function results27class CachedDict(dict):28 def __init__(self, func):29 self.func = func3031 def __missing__(self, key):32 result = self.func(key)33 self[key] = result34 return result3536square_cache = CachedDict(lambda x: x ** 2)37print(square_cache[5]) # 25 (computed)38print(square_cache[5]) # 25 (cached)
vs __getattr__:
__missing__ for dict key access.__getattr__ for attribute access.