substitution __str__ method of an instance

N

netimen

I couldn't substitute __str__ method of an instance. Though I managed
to substitute ordinary method of an instance:

from types import MethodType

class Foo(object):
pass

class Printer(object):

def __call__(self, obj_self):
return 'printed'

f = Foo()

f.printer = MethodType(Printer(), f, Foo)
print f.printer() # works fine - I get: 'printed'

print f # get: <__main__.Foo object at 0x00D69C10>
f.__str__ = MethodType(Printer(), f, Foo)
print f # still get: <__main__.Foo object at 0x00D69C10>. Why?
Foo.__str__ = MethodType(Printer(), None, Foo)
print f # works fine - I get: 'printed'


How can I substitute __str__ method of an instance?
 
D

Diez B. Roggisch

netimen said:
I couldn't substitute __str__ method of an instance. Though I managed
to substitute ordinary method of an instance:

from types import MethodType

class Foo(object):
pass

class Printer(object):

def __call__(self, obj_self):
return 'printed'

f = Foo()

f.printer = MethodType(Printer(), f, Foo)
print f.printer() # works fine - I get: 'printed'

print f # get: <__main__.Foo object at 0x00D69C10>
f.__str__ = MethodType(Printer(), f, Foo)
print f # still get: <__main__.Foo object at 0x00D69C10>. Why?
Foo.__str__ = MethodType(Printer(), None, Foo)
print f # works fine - I get: 'printed'


How can I substitute __str__ method of an instance?

You can't. Special methods are only looked up on classes.

Diez
 
D

Diez B. Roggisch

Christian said:
It's not possible. For performance and other reasons most __*__ methods
are looked up on the type only.

Is that documented somewhere? I *know* it is that way, yet I'd like to have
place to read up on it (and point to when this question pops up)

Diez
 
B

Bruno Desthuilliers

netimen a écrit :
I couldn't substitute __str__ method of an instance. Though I managed
to substitute ordinary method of an instance:

from types import MethodType

class Foo(object):
pass

class Printer(object):

def __call__(self, obj_self):
return 'printed'

f = Foo()

f.printer = MethodType(Printer(), f, Foo)
print f.printer() # works fine - I get: 'printed'

print f # get: <__main__.Foo object at 0x00D69C10>
f.__str__ = MethodType(Printer(), f, Foo)
print f # still get: <__main__.Foo object at 0x00D69C10>. Why?
Foo.__str__ = MethodType(Printer(), None, Foo)
print f # works fine - I get: 'printed'


How can I substitute __str__ method of an instance?

Now that others told you you couldn't do so, there's eventually a
workaround - that is, if you have the hand on class Foo:

class Foo(object):
def __str__(self):
printer = getattr(self, 'printer', super(Foo, self).__str__)
return printer()

HTH
 
S

Steven D'Aprano

It's not possible. For performance and other reasons most __*__ methods
are looked up on the type only.

Christian

However, you can dispatch back to the instance if you really must:


class MyObj(object):
def __init__(self):
self.__str__ = lambda self: "I'm an object!"
def __str__(self):
return self.__str__(self)


But honestly, this sounds like a bad idea. If instances of the one class
have such radically different methods that they need to be treated like
this, I question whether they actually belong in the same class.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top