I use python3.7 and for some application create a class inherited from a dict, but have a problem to implement items() and values() methods to made it work correctly. This class overrides many methods, but here I placed a very simplified example just to illustrate exact problem:
class MyFunction:
def __call__(self):
return 5
class MyDict(dict):
def __getitem__(self, key):
item = super().__getitem__(key)
if isinstance(item, MyFunction):
return item()
else:
return item
def get(self, key, default=None):
if self.__contains__(key):
return self.__getitem__(key)
if isinstance(default, MyFunction):
return default()
return default
# def __copy__(self):
# return type(self)(self)
#
# def copy(self):
# return self.__copy__()
# def __iter__(self):
# return super().__iter__()
d = MyDict(a=MyFunction(), b=3)
I want than I get a value by key instances of MyFunction be called. This works well:
for k in d:
print(k, d[k])
and prints the expected output:
a 5
b 3
But these two do not:
for v in d.values():
print(v)
for k, v in d.items():
print(k, v)
They print the function's repr.
How can I achive them to call __getitem__?
Remark: It can be some kind of dict built-in class optimization (I would like to not inherit form UserDict or Mapping). For example if I uncomment:
def __iter__(self):
return super().__iter__()
The calls:
new_d = d.copy()
new_d = dict(d)
new_d = dict(**d)
will call the __getitem__