If you do not separate the arguments from the called, I do not think this is possible. However, this should work:
class MySettingsDict(dict): def __getitem__(self, item): function, arg = dict.__getitem__(self, item) return function(arg) def expensive_to_compute(arg): return arg * 3
And now:
>>> settings = MySettingsDict({ 'expensive1': (expensive_to_compute, 1), 'expensive2': (expensive_to_compute, 2), }) >>> settings['expensive1'] 3 >>> settings['expensive2'] 6
Edit:
You can also cache expensive_to_compute results if they are available multiple times. Something like that
class MySettingsDict(dict): def __getitem__(self, item): value = dict.__getitem__(self, item) if not isinstance(value, int): function, arg = value value = function(arg) dict.__setitem__(self, item, value) return value
And now:
>>> settings.values() dict_values([(<function expensive_to_compute at 0x9b0a62c>, 2), (<function expensive_to_compute at 0x9b0a62c>, 1)]) >>> settings['expensive1'] 3 >>> settings.values() dict_values([(<function expensive_to_compute at 0x9b0a62c>, 2), 3])
You can also override other dict methods, depending on how you want to use the dict.
source share