Last active
February 25, 2025 21:50
-
-
Save sohang3112/f787b587202ead7fab916332afbea42b to your computer and use it in GitHub Desktop.
Re-implementing DefaultDict (from Python standard library) using __missing__ dunder method
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Using dict __missing__() to implement DefaultDict.""" | |
from typing import Any, Callable | |
class DefaultDict(dict): | |
"""Implementing typing.DefaultDict. | |
A dict that returns a default value (instead of raising KeyError) when a key is missing. | |
>>> d = DefaultDict(list, {'a': 1, 'b': 2}) | |
>>> d['a'] | |
1 | |
>>> d['c'].append(0) | |
>>> d # accessing 'c' key creates a new key-value pair, just like stdlib typing.DefaultDict | |
DefaultDict(<class 'list'>, {'a': 1, 'b': 2, 'c': [0]}) | |
>>> DefaultDict(0, {'a': 1, 'b': 2}) | |
Traceback (most recent call last): | |
... | |
TypeError: Expected callable as default_func, but got <class 'int'> | |
""" | |
def __init__(self, default_func: Callable[[], Any], *args, **kwargs): | |
super().__init__(*args, **kwargs) | |
if not callable(default_func): | |
raise TypeError(f"Expected callable as default_func, but got {type(default_func)}") | |
self._default_func = default_func | |
def __missing__(self, key): | |
self[key] = val = self._default_func() | |
return val | |
def __repr__(self): | |
return f"DefaultDict({self._default_func}, {super().__repr__()})" | |
if __name__ == '__main__': | |
import doctest | |
doctest.testmod() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Reddit post about this: https://www.reddit.com/r/learnpython/comments/1ixporv/example_of_using_missing_dunder_method_to/