I want to define a defaultdict, so that if the key is missing, its value should be f'You can set {key} to inject configuration here
Consider the following code
from collections import defaultdict
# Valid, but the default value for all key will be empty string.
d1 = defaultdict(str)
d1['post_simulation'] # return ''
# This is what I intend to do,
# but it is invalid as the default_factory won't take any arguments.
d2 = defaultdict(lambda k: f'#You can inject text here by setting {k}')
d2['post_simulation']
# TypeError: <lambda>() missing 1 required positional argument: 'k'
Is there any tech that I can do this in Python by using defaultdict or other data structure?
>Solution :
Yes, by overriding the default __missing__ method:
from collections import defaultdict
class MyDefaultDict(defaultdict):
def __missing__(self, key):
self[key] = f'#You can inject text here by setting {key}'
return self[key]
d = MyDefaultDict()
print(d["foo"])
# => #You can inject text here by setting foo
You can generalise it like this:
from collections import defaultdict
class LambdaDefaultDict(defaultdict):
def __init__(self, missing, *args, **kwargs):
super().__init__(None, *args, **kwargs)
self.missing = missing
def __missing__(self, key):
self[key] = self.missing(key)
return self[key]
d = LambdaDefaultDict(lambda k: f'#You can inject text here by setting {k}')
print(d["foo"])
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
There has to be a better name for this than LambdaDefaultDict.