Functions, callable objects, and bound/unbound methods

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

    Functions, callable objects, and bound/unbound methods

    If I do this:

    def f(self): print self

    class c1: pass

    setattr(c1, 'm1', f)

    Then f is automagically transmogrified into the appropriate sort of
    method depending on how it is used:
    >>c1.m1
    <unbound method c1.f>
    >>c1().m1
    <bound method c1.f of <__main__.c1 instance at 0x51e738>>
    >>c1().m1()
    <__main__.c1 instance at 0x51ec60>

    Note that m1 gets passed a self argument.

    The same automatic transmogrificat ion does not happen if I use an
    callable instance instead of an actual function object:

    class callable:
    def __call__(self, *args, **kw): return args, kw
    >>setattr(c1, 'm2', callable())
    >>c1.m2
    <__main__.calla ble instance at 0x51e738>
    >>c1().m2
    <__main__.calla ble instance at 0x51e738>
    >>c1().m2()
    ((), {})

    Note that no selfarg has been passed to m2.

    The reason I want to do this is that I want to implement a trace
    facility that traces only specific class methods. I want to say:

    trace(c1.m1)

    and have c1.m1 be replaced with a wrapper that prints debugging info
    before actually calling the old value of m1. The reason I want that to
    be an instance of a callable class instead of a function is that I need
    a place to store the old value of the method so I can restore it, and I
    don't want to start building a global data structure because that gets
    horribly ugly, and a callable class is the Right Thing -- if there's a
    way to actually make it work.

    Is there? I tried the obvious things (like making callable inherit from
    function, and adding im_func and im_self attribuetes) but they didn't
    work.

    Thanks,
    rg
  • Duncan Booth

    #2
    Re: Functions, callable objects, and bound/unbound methods

    Ron Garret <rNOSPAMon@flow net.comwrote:
    I want to say:
    >
    trace(c1.m1)
    >
    and have c1.m1 be replaced with a wrapper that prints debugging info
    before actually calling the old value of m1. The reason I want that
    to be an instance of a callable class instead of a function is that I
    need a place to store the old value of the method so I can restore it,
    and I don't want to start building a global data structure because
    that gets horribly ugly, and a callable class is the Right Thing -- if
    there's a way to actually make it work.
    >
    Is there? I tried the obvious things (like making callable inherit
    from function, and adding im_func and im_self attribuetes) but they
    didn't work.
    Read "Functions and Methods" in


    You need to implement a __get__ method on your class.

    Comment

    • Michele Simionato

      #3
      Re: Functions, callable objects, and bound/unbound methods

      Duncan Booth wrote:
      Ron Garret <rNOSPAMon@flow net.comwrote:
      >
      I want to say:

      trace(c1.m1)

      and have c1.m1 be replaced with a wrapper that prints debugging info
      before actually calling the old value of m1. The reason I want that
      to be an instance of a callable class instead of a function is that I
      need a place to store the old value of the method so I can restore it,
      and I don't want to start building a global data structure because
      that gets horribly ugly, and a callable class is the Right Thing -- if
      there's a way to actually make it work.

      Is there? I tried the obvious things (like making callable inherit
      from function, and adding im_func and im_self attribuetes) but they
      didn't work.
      >
      Read "Functions and Methods" in

      >
      You need to implement a __get__ method on your class.
      See also



      for an example and some discussion.

      Michele Simionato

      Comment

      • Kent Johnson

        #4
        Re: Functions, callable objects, and bound/unbound methods

        Ron Garret wrote:
        The reason I want to do this is that I want to implement a trace
        facility that traces only specific class methods. I want to say:
        >
        trace(c1.m1)
        >
        and have c1.m1 be replaced with a wrapper that prints debugging info
        before actually calling the old value of m1. The reason I want that to
        be an instance of a callable class instead of a function is that I need
        a place to store the old value of the method so I can restore it, and I
        don't want to start building a global data structure because that gets
        horribly ugly, and a callable class is the Right Thing -- if there's a
        way to actually make it work.
        If the only reason for a callable class is to save a single value (the
        original function), you could instead store it as an attribute of the
        wrapper function.

        Kent

        Comment

        • Kent Johnson

          #5
          Re: Functions, callable objects, and bound/unbound methods

          Ron Garret wrote:
          The reason I want to do this is that I want to implement a trace
          facility that traces only specific class methods. I want to say:
          >
          trace(c1.m1)
          >
          and have c1.m1 be replaced with a wrapper that prints debugging info
          before actually calling the old value of m1. The reason I want that to
          be an instance of a callable class instead of a function is that I need
          a place to store the old value of the method so I can restore it, and I
          don't want to start building a global data structure because that gets
          horribly ugly, and a callable class is the Right Thing -- if there's a
          way to actually make it work.
          If the only reason for a callable class is to save a single value (the
          original function), you could instead store it as an attribute of the
          wrapper function.

          Kent

          Comment

          • Ron Garret

            #6
            Re: Functions, callable objects, and bound/unbound methods

            In article <457065D6.70604 06@kentsjohnson .com>,
            Kent Johnson <kent@kentsjohn son.comwrote:
            Ron Garret wrote:
            The reason I want to do this is that I want to implement a trace
            facility that traces only specific class methods. I want to say:

            trace(c1.m1)

            and have c1.m1 be replaced with a wrapper that prints debugging info
            before actually calling the old value of m1. The reason I want that to
            be an instance of a callable class instead of a function is that I need
            a place to store the old value of the method so I can restore it, and I
            don't want to start building a global data structure because that gets
            horribly ugly, and a callable class is the Right Thing -- if there's a
            way to actually make it work.
            >
            If the only reason for a callable class is to save a single value (the
            original function), you could instead store it as an attribute of the
            wrapper function.
            I considered that, and I may yet fall back on it, but 1) I wanted to
            understand how these things worked and 2) I need a way to tell when a
            method has been traced, and isinstance(meth od, tracer) seems less
            hackish to me than hasattr(method, 'saved_function ').

            rg

            Comment

            • Ron Garret

              #7
              Re: Functions, callable objects, and bound/unbound methods

              In article <1164968507.519 962.325820@j44g 2000cwa.googleg roups.com>,
              "Michele Simionato" <michele.simion ato@gmail.comwr ote:
              Duncan Booth wrote:
              Ron Garret <rNOSPAMon@flow net.comwrote:
              I want to say:
              >
              trace(c1.m1)
              >
              and have c1.m1 be replaced with a wrapper that prints debugging info
              before actually calling the old value of m1. The reason I want that
              to be an instance of a callable class instead of a function is that I
              need a place to store the old value of the method so I can restore it,
              and I don't want to start building a global data structure because
              that gets horribly ugly, and a callable class is the Right Thing -- if
              there's a way to actually make it work.
              >
              Is there? I tried the obvious things (like making callable inherit
              from function, and adding im_func and im_self attribuetes) but they
              didn't work.
              Read "Functions and Methods" in


              You need to implement a __get__ method on your class.
              >
              See also
              >

              bcdf/93503c5b9c66226 e?lnk=gst&q=sim ionato+subclass ing+FunctionTyp e&rnum=1&hl=e
              n#93503c5b9c662 26e
              >
              for an example and some discussion.
              >
              Michele Simionato
              Thanks!

              rg

              Comment

              Working...