
A while back, I wrote a post showing how to handle missing dict keys. In summary: Using...
A while back, I wrote a post showing how to handle missing dict keys. In summary:
setdefaultdefaultdict__missing__While the advice there still stands, I've been reading through Fluent Python and came across two things worth being aware of when subclassing dict:
__contains__ doesn't call __missing__, so k in d returns False for keys not yet set, even if __missing__ would handle themdict.get doesn't call __missing__, so .get(k) won't use your custom defaultBoth are by design and often what you want. __missing__ is only used by d[key], not other dict methods. Even defaultdict follows the same rule: only d[key] triggers the default factory and methods like .get() and in do not.
Overriding get is tempting but tricky. A naive implementation might look like this:
class M(dict):
def __missing__(self, key):
value = "my default value"
self[key] = value
return value
def get(self, key, default=None):
try:
return self[key] # triggers __missing__ if key is absent
except KeyError:
return default # dead code, never reached
This doesn't work. self[key] calls __missing__ instead of raising KeyError, so the except block is unreachable and default is effectively useless:
>>> m = M()
>>> m.get("x", "fallback")
'my default value' # expected "fallback", got __missing__ value instead
>>> m
{'x': 'my default value'} # side effect: key was set in the dict
There's no clean way to honour both the __missing__ default and the default parameter in get. It's better to accept that get and __missing__ serve different purposes and leave get alone. Note that this applies to dict subclasses specifically. If you subclass UserDict instead, get calls __getitem__ internally and __missing__ is triggered. With a dict subclass, get is implemented in C and bypasses __getitem__ altogether. The behaviour is inconsistent across the standard library depending on which base class you use.
As for __contains__, overriding it is a design decision. If your subclass provides a value for every possible key, returning True always can be reasonable:
def __contains__(self, key):
return True
Only thing to keep in mind in this case is that "x" in m returns True even when m is {}, which looks confusing.
gemmaI ported the whole Gemma-4 family — E2B, E4B, 12B, 31B, and the 26B-A4B MoE — to run on...
communityHey DEV, I'm Tobore. Let's actually connect. I've been on here for a while now, mostly writing and...
ai(yep, kinda clickbait, just for the funsies 😊) At the beginning of the year, I relaunched my...
aiMy laptop was sitting idle with the fan at full tilt. Nothing was running that I knew of. The culprit...
githubactionsI Built a Thing! TL;DR — Google Gemini-based Pull Request reviews and Issue Triaging for...
aiI've been hearing the word "harness" thrown around a lot lately. I assumed it just meant "the IDE" or...
Workflows from the Neura Market marketplace related to this DeepSeek resource