Function returns a function

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

    #1

    Function returns a function

    Hello,

    I want a "function factory" function in python. To do this I made a class like
    such (this is for Tkinter, in case your wondering):

    class FunctionMaker:
    def __init__(self, avar, function, label)
    self.var = avar
    self.function = function
    self.label = label
    def __call__(self, e=None):
    self.avar.set(s elf.label)
    self.function()

    It seems that it would make more sense to make this a function and add it to
    the mixin I am writing. But I'm not quite sure how to do this without making
    lambdas, which seem a little messy and also look to be on the brink of
    deprecation (really not trying to start a lambda pro/con thread here).

    Any ideas on how to do this with a regular function, or is the way I've done
    it the pythonic choice?

    James

    --
    James Stroud
    UCLA-DOE Institute for Genomics and Proteomics
    Box 951570
    Los Angeles, CA 90095


  • Paul Rubin

    #2
    Re: Function returns a function

    James Stroud <jstroud@mbi.uc la.edu> writes:[color=blue]
    > Any ideas on how to do this with a regular function, or is the way I've done
    > it the pythonic choice?[/color]

    I think you're trying to do something like this:

    def FunctionMaker(a var, func, label):
    def callback():
    avar.set(label)
    func()
    return callback

    Comment

    • James Stroud

      #3
      Re: Function returns a function

      Thank you Paul, this makes much more sense.

      James

      On Tuesday 06 September 2005 02:16 pm, Paul Rubin wrote:[color=blue]
      >     def FunctionMaker(a var, func, label):
      >        def callback():
      >           avar.set(label)
      >           func()
      >        return callback[/color]

      --
      James Stroud
      UCLA-DOE Institute for Genomics and Proteomics
      Box 951570
      Los Angeles, CA 90095


      Comment

      • Gregory Bond

        #4
        Re: Function returns a function

        Paul Rubin wrote:
        [color=blue]
        >
        > def FunctionMaker(a var, func, label):
        > def callback():
        > avar.set(label)
        > func()
        > return callback[/color]

        I've seen this idiom a lot and I know _what_ it does..... but I can't
        work _how_ it does it. How does the name binding work so that "avar" in
        the returned function still references the object passed into the
        (long-distant!) FunctionMaker() call?

        Web pages / turotial ptrs etc gladly accepted.

        Comment

        • Aldo Cortesi

          #5
          Re: Function returns a function

          Thus spake Gregory Bond (gnb@itga.com.a u):
          [color=blue]
          > Paul Rubin wrote:
          >[color=green]
          > >
          > > def FunctionMaker(a var, func, label):
          > > def callback():
          > > avar.set(label)
          > > func()
          > > return callback[/color]
          >
          > I've seen this idiom a lot and I know _what_ it does.....
          > but I can't
          > work _how_ it does it. How does the name binding work so
          > that "avar" in
          > the returned function still references the object passed
          > into the
          > (long-distant!) FunctionMaker() call?
          >
          > Web pages / turotial ptrs etc gladly accepted.[/color]

          The lexical scope within which a function is declared is
          made available to the function when it is run. This is done
          by storing the values of free variables within the declared
          function in the func_closure attribute of the created
          function object.

          If you want to read more, the keyword you're looking for is
          "closure" - a quick search on Google for "python closure"
          should satisfy your curiosity handily. There is also a neat
          recipe for inspecting the values kept in the func_closure
          attribute of function objects directly:








          Cheers,


          Aldo



          --
          Aldo Cortesi
          aldo@nullcube.c om

          Off: (02) 9283 1131
          Mob: 0419 492 863

          Comment

          • Paul Rubin

            #6
            Re: Function returns a function

            Aldo Cortesi <aldo@nullcube. com> writes:[color=blue]
            > The lexical scope within which a function is declared is
            > made available to the function when it is run. This is done
            > by storing the values of free variables within the declared
            > function in the func_closure attribute of the created
            > function object.[/color]

            Actually not quite right:

            a = []
            for i in range(5):
            a.append(lambda : i) # i is free in the lambda
            print [f() for f in a]

            prints [4,4,4,4,4] instead of [0,1,2,3,4]. The value of i has not
            been copied into the closure. Rather, the closure has a cell bound to
            the same place that i is bound. So:

            for i in range(5):
            def f():
            j = i # bind a new variable "j" and assign the value from i
            return lambda: j # j is free and its value doesn't change
            a.append(f())
            print [f() for f in a]

            prints [0,1,2,3,4]. There's a Pythonic idiom using default args:

            a = []
            for i in range(5):
            a.append(lambda i=i: i) # the "inner" i is free in the lambda
            print [f() for f in a]

            Closures like may look a little surprising in Python but they're a
            standard technique in Scheme. The classic textbook "Structure and
            Interpretation of Computer Programming" explains it all. Full text is
            online at:

            http://mitpress.mit.edu/sicp/

            Comment

            • Gregory Bond

              #7
              Re: Function returns a function

              Paul Rubin wrote:[color=blue]
              > Aldo Cortesi <aldo@nullcube. com> writes:[/color]


              Thanks to Paul and Aldo... one more question on the implementation.

              Why is the func_closure a tuple of Cells and not just a tuple of
              objects? Why the extra level of indirection?

              Comment

              Working...