You can emulate a method by dynamically assign a callable to an equally named attribute of your class. This basically works for common as well as for dunder methods. But the lambda version does not work as hook for the interpreter's mechanisms:
>>> class Foo:
... def bar(self):
... return 'bar'
... def __repr__(self):
... return 'repr'
... f = Foo()
>>> f.bar()
'bar'
>>> f.__repr__()
'repr'
>>> print(f)
repr
>>> class Foo:
... def __init__(self):
... self.bar = lambda: 'bar'
... self.__repr__ = lambda: 'repr'
... f = Foo()
>>> f.bar()
'bar'
>>> f.__repr__()
'repr'
>>> print(f)
<__main__.Foo object at 0x000000FC7A879EB8>
Why is that?