I have recently come across MethodType
which allows to do arguably hacky but fun stuff like:
from types import MethodType
class MyClass():
def __init__(self, n : int):
self.list_of_items = list(range(n))
def __getitem__(self, idx):
return self.list_of_items[idx]
def foo(self):
return "foo"
def bar(self):
return "bar"
a = MyClass(10)
a.foo = MethodType(bar, a)
a.foo()
## prints bar
a[0]
# 0 (int) is printed
But what if I wanted to dynamically decorate the __getitem__
of a
in a similar spirit ?
The first idea that comes to mind is to do:
def new_getitem(self, idx):
return str(self.__getitem__(idx))
a.__getitem__ = MethodType(new_getitem, a)
However this has two problems first 1. __getitem__
isn't changed in the sense that []
syntax is not modified.
a[0]
# 0 (int) is printed
Which might be explained by some funny business happening in the init of the instance to tie []
to __getitem__
What is worst is that explicitly calling __getitem__
:
a.__getitem__(0)
runs into infinite recursion as we are redefining __getitem__
infinitely.
I was wondering if there was a syntax allowing to perform this hack so that:
a[0] = "0" (string)
I am open to any solution that allows to dynamically affect the instance's []
(using MethodType is not a requirement).