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' >>> ```

Original source

Related problems