substitution __str__ method of an instance

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • netimen

    substitution __str__ method of an instance

    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(Prin ter(), f, Foo)
    print f.printer() # works fine - I get: 'printed'

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


    How can I substitute __str__ method of an instance?
  • Diez B. Roggisch

    #2
    Re: substitution __str__ method of an instance

    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(Prin ter(), f, Foo)
    print f.printer() # works fine - I get: 'printed'
    >
    print f # get: <__main__.Foo object at 0x00D69C10>
    f.__str__ = MethodType(Prin ter(), f, Foo)
    print f # still get: <__main__.Foo object at 0x00D69C10>. Why?
    Foo.__str__ = MethodType(Prin ter(), 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

    Comment

    • Christian Heimes

      #3
      Re: substitution __str__ method of an instance

      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

      Comment

      • Diez B. Roggisch

        #4
        Re: substitution __str__ method of an instance

        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

        Comment

        • Bruno Desthuilliers

          #5
          Re: substitution __str__ method of an instance

          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(Prin ter(), f, Foo)
          print f.printer() # works fine - I get: 'printed'
          >
          print f # get: <__main__.Foo object at 0x00D69C10>
          f.__str__ = MethodType(Prin ter(), f, Foo)
          print f # still get: <__main__.Foo object at 0x00D69C10>. Why?
          Foo.__str__ = MethodType(Prin ter(), 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

          Comment

          • Bruno Desthuilliers

            #6
            Re: substitution __str__ method of an instance

            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)
            Objects, values and types: Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations between objects. Even code is represented by objects. Ev...


            Comment

            • Steven D'Aprano

              #7
              Re: substitution __str__ method of an instance

              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__(se lf)


              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

              Comment

              • Duncan Booth

                #8
                Re: substitution __str__ method of an instance

                Steven D'Aprano <steve@REMOVE-THIS-cybersource.com .auwrote:
                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__(se lf)
                >
                >
                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(instanc e, fn=None):
                if fn is None:
                def fn(self): return "I'm an object"
                Wrapper = type(instance._ _class__.__name __, (instance.__cla ss__,),
                {'__str__':fn})
                instance.__clas s__ = 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

                Comment

                Working...