Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why monkey patching (via setattr) magic methods does not work?

Tags:

python

x is an instance of some object:

> x = type('someobject', (), {})()
> repr(x)
<someobject object at 0x10172d990>

Why monkey patching a magic method (e.g. __repr__) does not work?

> setattr(x, '__repr__', lambda self: f'<someobj {id(self)}>')
> repr(x)
<someobject object at 0x10172d990>

(original __repr__ is used)

> x.__repr__(x)
<someobj 4319271312>
like image 300
fferri Avatar asked Mar 06 '26 18:03

fferri


1 Answers

You need to set the repr object on the type, not the class itself:

x = type('someobject', (), {})()
print(repr(x))
# <__main__.someobject object at 0x7f91c2c664d0>
type(x).__repr__=lambda self: f'<someobj {id(self)}>'
print(repr(x))
# <someobj 140264014767312>

Special methods work a bit weired this way.

You can monkey patch a single instance like this:

def override_repr(obj):
    # create a new subclass that inherits from the objects original type
    new_type = type(type(obj).__name__, (type(obj),), {})
    # Override the repr special method
    new_type.__repr__ = lambda self:hex(id(self))
    # change the type of the object to the new subtype
    obj.__class__=new_type

class M:
   pass

k = M()
override_repr(k)
print(repr(k))
like image 171
mousetail Avatar answered Mar 08 '26 06:03

mousetail