[Python-Dev] repr(x) != x.__repr__()

Guido van Rossum guido@python.org
Thu, 28 Mar 2002 10:28:12 -0500


> This phenomenon is not really specific to repr(). It occurs with
> new-style classes when methods are assigned.
> 
> Example:
> 
> class A(object):
>   def __repr__(self):
>     return 'abc'
> 
> >>>a = A()
> >>>a.__repr__ = lambda: 'abc'

You meant '123' there. :-)

> >>>repr(a)
> 'abc'
> >>>a.__repr__()
> '123'
> 
> Whenever the method is accessed by Python code it sees the assigned
> method in the object's __dict__.  Builtins like repr(), iter() etc,
> see the original class method.  With classic objects both Python and
> C code see the assigned function.  This is bug #515336 on
> sourceforge.

I'm probably going to reject this bug as "won't fix".  I specifically
put code in the new classes to create this behavior.  It's partly a
performance hack: many operations become much slower if they have to
check the instance __dict__ first.  But I also believe it's poor
style to override a system operation on the instance rather than on
the class.  If you want to be able to override behavior per instance,
use this:

  class A(object):
    def __repr__(self):
      return self.repr()
    def repr(self):
      return 'abc'

  a = A()
  a.repr = lambda: '123'
  assert repr(a) == a.__repr__() == '123'

> Is anyone aware of any other cases where C code and Python code
> don't see objects the same way?

Yes, a+b is not the same as a.__add__(b).  a[i:j] is not the same as
a.__getslice__(i, j).

--Guido van Rossum (home page: http://www.python.org/~guido/)