2

I'm having a problem in Python 3.4 and would appreciate any help and/or explanation:

Basically I have a class with a function that should return an instance of another class, but with a modified string representation so that I can later print() that instance and see the Stuff added in that function.

What I don't understand is that even though I seem to be able to change the str and repr methods of that instance, print() will still use the original representation.

This is a boiled-down example that essentially shows what I tried:

class A():
  def __str__(self):
    return('AAA')
class B():
  def output(self):
    return('BBB')
  def run(self):
    a = A()
    print("if str(a)({}) equals a.__str__()({})...".format(str(a), a.__str__()))
    a.__str__ = self.output
    a.__repr__ = self.output
    print("... why not now? (str(a) = {} while a.__str__() = {}".format(str(a), a.__str__()))
    return a
b = B()
a=b.run()
print("print a: {}, str(a): {}, a.__str__(): {}, a.__repr__():{}".format(a, str(a), a.__str__(), a.__repr__()))

Can someone please explain this to me? Thanks for your time, guys!

Edit: forgot the output, sorry:

[xxx@localhost ~]$ python test.py
if str(a)(AAA) equals a.__str__()(AAA)...
... why not now? (str(a) = AAA while a.__str__() = BBB
print a: AAA, str(a): AAA, a.__str__(): BBB, a.__repr__():BBB

Edit: Thanks Martijn Pieters for the explanation!

I changed my code to :

class A():
  def __init__(self):
    self.str = 'AAA'

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

class B():

  def run(self):
    a = A()
    a.str = 'BBB'
    print(a, str(a), a.__str__())
    return a

b = B()
a=b.run()

print("print a: {}, str(a): {}, a.__str__(): {}".format(a, str(a), a.__str__()))

And I now get the output I want:

python test.py
BBB BBB BBB
print a: BBB, str(a): BBB, a.__str__(): BBB
Egniter
  • 23
  • 3

2 Answers2

2

Special methods are always called on the type; for instances, that is the class. See the Special method lookup:

For custom classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary.

This means that you cannot add __str__ or __repr__ methods to the instance and expect those to be used.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0
a.__class__.__str__ = self.output
a.__class__.__repr__ = self.output

But in Python2.7 your original code works correctly. Hmm.

guest
  • 1