5

Here is the code:

class Dummy(object):
    def __init__(self, v):
        self.ticker = v


def main():
        def _assign_custom_str(x):
            def _show_ticker(t):                
                return t.ticker
            x.__str__ = _show_ticker
            x.__repr__ = _show_ticker
            return x


    a = [Dummy(1), Dummy(2)]

    a1 = [_assign_custom_str(t) for t in a]
    print a1[1]
    # print a1[1].__str__ # test to if orig __str__ is replaced

I was hoping to see the output like this

2

However, instead I see the standard representation:

<__main__.Dummy object at 0x01237730>

Why?

Anthony Kong
  • 37,791
  • 46
  • 172
  • 304
  • Note that this *does* work with old-style classes (not extending `object`). See my question for the difference: http://stackoverflow.com/questions/16062293/replacing-str-in-new-style-class – BoppreH Apr 17 '13 at 14:34

2 Answers2

15

Magic methods are only guaranteed to work if they're defined on the type rather than on the object.

For example:

def _assign_custom_str(x):
        def _show_ticker(self):                
            return self.ticker
        x.__class__.__str__ = _show_ticker
        x.__class__.__repr__ = _show_ticker
        return x

But note that will affect all Dummy objects, not just the one you're using to access the class.

agf
  • 171,228
  • 44
  • 289
  • 238
  • 1
    [updated link](https://docs.python.org/3/reference/datamodel.html#special-method-lookup) – dshanahan Jun 10 '21 at 21:10
  • @dshanahan Thanks, fixed in the answer. In the future please suggest an edit rather than leaving a comment. – agf Jun 11 '21 at 03:29
1

if you want to custmize __str__ for every instance, you can call another method _str in __str__, and custmize _str:

class Dummy(object):
    def __init__(self, v):
        self.ticker = v

    def __str__(self):
        return self._str()

    def _str(self):
        return super(Dummy, self).__str__()

def main():
    a1 = Dummy(1)
    a2 = Dummy(2)

    a1._str = lambda self=a1:"a1: %d" % self.ticker
    a2._str = lambda self=a2:"a2: %d" % self.ticker

    print a1
    print a2    

    a1.ticker = 100
    print a1

main()

the output is :

a1: 1
a2: 2
a1: 100
HYRY
  • 94,853
  • 25
  • 187
  • 187