Re: substitution __str__ method of an instance

2008-10-24 Thread Duncan Booth
Steven D'Aprano [EMAIL PROTECTED] wrote:

 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.
 

Another option would be to just change the class of the object:

 class C(object):
pass

 c = C()
 print c
__main__.C object at 0x01180C70
 def wrapstr(instance, fn=None):
if fn is None:
def fn(self): return I'm an object
Wrapper = type(instance.__class__.__name__, (instance.__class__,), 
{'__str__':fn})
instance.__class__ = Wrapper


 wrapstr(c)
 print c
I'm an object
 isinstance(c, C)
True
 type(c)
class '__main__.C'
 wrapstr(c, lambda s: object %s at %s % (type(s).__name__, id(s)))
 print c
object C at 18353264

(I'll leave enhancing wrapstr so that it avoids multiple levels of 
wrapping as an exercise for anyone who actually wants to use it.)

-- 
Duncan Booth http://kupuguy.blogspot.com
--
http://mail.python.org/mailman/listinfo/python-list


substitution __str__ method of an instance

2008-10-23 Thread 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?
--
http://mail.python.org/mailman/listinfo/python-list


Re: substitution __str__ method of an instance

2008-10-23 Thread Christian Heimes

netimen wrote:

How can I substitute __str__ method of an instance?


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


Christian

--
http://mail.python.org/mailman/listinfo/python-list


Re: substitution __str__ method of an instance

2008-10-23 Thread Diez B. Roggisch
netimen wrote:

 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
--
http://mail.python.org/mailman/listinfo/python-list


Re: substitution __str__ method of an instance

2008-10-23 Thread Diez B. Roggisch
Christian Heimes wrote:

 netimen wrote:
 How can I substitute __str__ method of an instance?
 
 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
--
http://mail.python.org/mailman/listinfo/python-list


Re: substitution __str__ method of an instance

2008-10-23 Thread 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
--
http://mail.python.org/mailman/listinfo/python-list


Re: substitution __str__ method of an instance

2008-10-23 Thread Bruno Desthuilliers

Diez B. Roggisch a écrit :

Christian Heimes wrote:


netimen wrote:

How can I substitute __str__ method of an instance?

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)


http://docs.python.org/reference/datamodel.html#special-method-lookup-for-new-style-classes

--
http://mail.python.org/mailman/listinfo/python-list


Re: substitution __str__ method of an instance

2008-10-23 Thread Steven D'Aprano
On Thu, 23 Oct 2008 10:55:56 +0200, Christian Heimes wrote:

 netimen wrote:
 How can I substitute __str__ method of an instance?
 
 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.




-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list