views:

253

answers:

3

Why does str(A()) seemingly call A.__repr__() and not dict.__str__() in the example below?

class A(dict):
    def __repr__(self):
        return 'repr(A)'
    def __str__(self):
        return dict.__str__(self)

class B(dict):
    def __str__(self):
        return dict.__str__(self)

print 'call: repr(A)  expect: repr(A)  get:', repr(A())   # works
print 'call: str(A)   expect: {}       get:', str(A())    # does not work
print 'call: str(B)   expect: {}       get:', str(B())    # works

Output:

call: repr(A)  expect: repr(A)  get: repr(A)
call: str(A)   expect: {}       get: repr(A)
call: str(B)   expect: {}       get: {}
+8  A: 

str(A()) does call __str__, in turn calling dict.__str__().

It is dict.__str__() that returns the value repr(A).

codeape
+2  A: 

I have modified the code to clear things out:

class A(dict):
   def __repr__(self):
      print "repr of A called",
      return 'repr(A)'
   def __str__(self):
      print "str of A called",
      return dict.__str__(self)

class B(dict):
   def __str__(self):
      print "str of B called",
      return dict.__str__(self)

And the output is:

>>> print 'call: repr(A)  expect: repr(A)  get:', repr(A())
call: repr(A)  expect: repr(A)  get: repr of A called repr(A)
>>> print 'call: str(A)   expect: {}       get:', str(A())
call: str(A)   expect: {}       get: str of A called repr of A called repr(A)
>>> print 'call: str(B)   expect: {}       get:', str(B())
call: str(B)   expect: {}       get: str of B called {}

Meaning that str function calls the repr function automatically. And since it was redefined with class A, it returns the 'unexpected' value.

rpr
+1  A: 

Hi,

I have posted a workaround solution to it. Check it out ... you might find it useful: http://blog.teltub.com/2009/10/workaround-solution-to-python-strrepr.html

P.S. Read the original post where I introduced the issue as well ... There problem is the unexpected behavior that catches you by surprise ...

Ehsan Foroughi