Overriding special methods on an instance
metaprogramming, python
Solution
Python usually doesn't call the special methods (those with name surrounded by `__`) on the instance, but only on the class. (Although this is an implementation detail, it's characteristic of CPython, the standard interpreter.) So there's no way to override `__repr__()` directly on an instance and make it work. Instead, you need to do something like so:
class A(object):
def __repr__(self):
return self._repr()
def _repr(self):
return object.__repr__(self)
Now you can override `__repr__()` on an instance by substituting `_repr()`.
Problem
Consider the following code: ``` >>> class A(object): ... pass ... >>> def __repr__(self): ... return "A" ... >>> from types import MethodType >>> a = A() >>> a <__main__.A object at 0x00AC6990> >>> repr(a) '<__main__.A object at 0x00AC6990>' >>> setattr(a, "__repr__", MethodType(__repr__, a, a.__class__)) >>> a <__main__.A object at 0x00AC6990> >>> repr(a) '<__main__.A object at 0x00AC6990>' >>> ``` Notice how repr(a) does not yield the expected result of "A"? I want to know why this is the case and if there is a way to achieve this... In contrast, the following example works however (Maybe because we're not trying to override a special method?): ``` >>> class A(object): ... def foo(self): ... return "foo" ... >>> def bar(self): ... return "bar" ... >>> from types import MethodType >>> a = A() >>> a.foo() 'foo' >>> setattr(a, "foo", MethodType(bar, a, a.__class__)) >>> a.foo() 'bar' >>> ```