Closures in python

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kasper B. Graversen

    Closures in python

    Having played with Smalltalk for the past month, I'm getting used to
    passing code as arguments to methods... how easy is it to do this in
    python? I haven't seen any recent postings on this subject here...

    \kasper
  • Ladvánszky Károly

    #2
    Re: Closures in python

    Try this.

    def f(n):
    return n*2

    def t(fnc_prm, n):
    return fnc_prm(n)

    t(f, 2)

    I hope it helps.

    Károly

    "Kasper B. Graversen" <kbilsted@it-c.dk> az alábbiakat írta a következo
    hírüzenetben: 9caba98e.030918 0208.692e9b68@p osting.google.c om...[color=blue]
    > Having played with Smalltalk for the past month, I'm getting used to
    > passing code as arguments to methods... how easy is it to do this in
    > python? I haven't seen any recent postings on this subject here...
    >
    > \kasper[/color]


    Comment

    • Syver Enstad

      #3
      Re: Closures in python

      kbilsted@it-c.dk (Kasper B. Graversen) writes:
      [color=blue]
      > Having played with Smalltalk for the past month, I'm getting used to
      > passing code as arguments to methods... how easy is it to do this in
      > python? I haven't seen any recent postings on this subject here...[/color]

      It is fairly straightforward :

      import sys

      def funcThatTakesCa llable(aCallabl e):
      aCallable('Some String')

      class MyClass:
      def myFunc():
      def myCallable(arg) :
      print arg
      funcThatTakesCa llable(myCallab le)
      funcThatTakesCa llable(self.ano therCallable)
      funcThatTakesCa llable(lambda arg: sys.stdout.writ e('%s\n' % arg))

      def anotherCallable (self, arg):
      print 'another', arg


      The major difference is that the anonymous form of a function (lambda)
      isn't allowed to contain statements, only an expression. This is
      rather crippling for Smalltalk/Ruby style coding and seems to lead to
      warts like list comprehensions instead of having simple methods in the
      collection interface that takes a block/lambda and calls this for each
      element of the collection.

      Example:

      newCollection = [each for each in collection if each != 'Sausage']

      newCollection = collection.sele ct(lambda each: each != 'Sausage')


      Comment

      • Daniel Dittmar

        #4
        Re: Closures in python

        Kasper B. Graversen wrote:[color=blue]
        > Having played with Smalltalk for the past month, I'm getting used to
        > passing code as arguments to methods... how easy is it to do this in
        > python? I haven't seen any recent postings on this subject here...[/color]

        There is no direct equivalent of code blocks in Python. Use Callables
        instead. Callables are

        - functions
        def mywrite (text):
        sys.stdout.writ e (text)
        variable = mywrite
        variable ('printed text')

        - bound methods, a method bound to a specific object
        variable = sys.stdout.writ e
        variable ('printed text')

        - lambda, unnamed functions, which can contain only one expression
        variable = lambda text: sys.stdout.writ e (text)
        variable ('printed text')

        - classes implementing the __call__ method
        class Writer:
        def __call__ (self, text):
        sys.stdout.writ e (text)
        variable = Writer ()
        variable ('printed text')

        Daniel



        Comment

        • Hallvard B Furuseth

          #5
          Re: Closures in python

          'closure' is a much-abused word.
          This is a closure over foo's x variable:

          def foo():
          x = 3
          def bar():
          x += 1
          return x
          return bar

          f = foo()
          print f() # print 4
          g = foo()
          print f() # print 5
          print g() # print 4

          ....or it would be, if it worked.

          --
          Hallvard

          Comment

          • Ladvánszky Károly

            #6
            Re: Closures in python

            Try this.

            def f(n):
            return n*2

            def t(fnc_prm, n):
            return fnc_prm(n)

            t(f, 2)

            I hope it helps.

            Károly


            "Kasper B. Graversen" <kbilsted@it-c.dk> az alábbiakat írta a következo
            hírüzenetben: 9caba98e.030918 0208.692e9b68@p osting.google.c om...[color=blue]
            > Having played with Smalltalk for the past month, I'm getting used to
            > passing code as arguments to methods... how easy is it to do this in
            > python? I haven't seen any recent postings on this subject here...
            >
            > \kasper[/color]


            Comment

            • Anton Vredegoor

              #7
              Re: Closures in python

              Hallvard B Furuseth <h.b.furuseth(n ospam)@usit.uio (nospam).no> wrote:
              [color=blue]
              >'closure' is a much-abused word.
              >This is a closure over foo's x variable:[/color]

              How about namespaces?
              [color=blue]
              >def foo():
              > x = 3
              > def bar():
              > x += 1
              > return x
              > return bar
              >
              >f = foo()
              >print f() # print 4
              >g = foo()
              >print f() # print 5
              >print g() # print 4
              >
              >...or it would be, if it worked.[/color]

              This works:

              def foo():
              class ns:pass
              ns.x = 3
              def bar():
              ns.x += 1
              return ns.x
              return bar

              Anton

              Comment

              • JCM

                #8
                Re: Closures in python

                Hallvard B Furuseth <h.b.furuseth(n ospam)@usit.uio (nospam).no> wrote:[color=blue]
                > 'closure' is a much-abused word.
                > This is a closure over foo's x variable:[/color]
                [color=blue]
                > def foo():
                > x = 3
                > def bar():
                > x += 1
                > return x
                > return bar[/color]
                [color=blue]
                > f = foo()
                > print f() # print 4
                > g = foo()
                > print f() # print 5
                > print g() # print 4[/color]
                [color=blue]
                > ...or it would be, if it worked.[/color]

                Python does have closures; the trouble is you can't rebind variables
                defined in arbitrary scopes--you can only rebind locals and globals.
                So you need some indirection for it to work:
                [color=blue][color=green][color=darkred]
                >>> def foo():[/color][/color][/color]
                ... x = [3]
                ... def bar():
                ... x[0] += 1
                ... return x[0]
                ... return bar
                ...[color=blue][color=green][color=darkred]
                >>> f = foo()
                >>> f()[/color][/color][/color]
                4[color=blue][color=green][color=darkred]
                >>> g = foo()
                >>> f()[/color][/color][/color]
                5[color=blue][color=green][color=darkred]
                >>> g()[/color][/color][/color]
                4

                This is actually one of my biggest complaints about Python. I'd like
                syntactic disambiguation between definition and assignment in order to
                have control over which scope you're assigning into.

                Comment

                • Hallvard B Furuseth

                  #9
                  Re: Closures in python

                  Anton Vredegoor wrote:[color=blue]
                  > Hallvard B Furuseth <h.b.furuseth(n ospam)@usit.uio (nospam).no> wrote:
                  >[color=green]
                  >> 'closure' is a much-abused word.
                  >> This is a closure over foo's x variable:[/color]
                  >
                  > How about namespaces?
                  > (...)[/color]

                  Nice! Being a Python newbie I needed JCM's explanation to figure out
                  how it worked, though. Nothing magic about classes at all...

                  --
                  Hallvard

                  Comment

                  • Hallvard B Furuseth

                    #10
                    Re: Closures in python

                    JCM wrote:[color=blue][color=green][color=darkred]
                    > >>> def foo():[/color][/color]
                    > ... x = [3]
                    > ... def bar():
                    > ... x[0] += 1
                    > (...)
                    >
                    > This is actually one of my biggest complaints about Python. I'd like
                    > syntactic disambiguation between definition and assignment in order to
                    > have control over which scope you're assigning into.[/color]

                    Maybe Python could be changed to let 'foo.x' inside function foo mean
                    the x variable in foo?

                    --
                    Hallvard

                    Comment

                    • Alex Martelli

                      #11
                      Re: Closures in python

                      nospam wrote:
                      [color=blue]
                      > JCM wrote:[color=green][color=darkred]
                      >> >>> def foo():[/color]
                      >> ... x = [3]
                      >> ... def bar():
                      >> ... x[0] += 1
                      >> (...)
                      >>
                      >> This is actually one of my biggest complaints about Python. I'd like
                      >> syntactic disambiguation between definition and assignment in order to
                      >> have control over which scope you're assigning into.[/color]
                      >
                      > Maybe Python could be changed to let 'foo.x' inside function foo mean
                      > the x variable in foo?[/color]

                      That would be backwards-incompatible, since foo.x already means
                      something -- the attribute x of object foo (yep, functions are objects
                      and can have attributes), which has no connection whatsoever with
                      the local variable x inside (some of the potentially many currently
                      active instances of) functions named foo.


                      Alex

                      Comment

                      • David Eppstein

                        #12
                        Re: Closures in python

                        In article <HBF.200309217b y@bombur.uio.no >,
                        Hallvard B Furuseth <h.b.furuseth(n ospam)@usit.uio (nospam).no> wrote:
                        [color=blue]
                        > JCM wrote:[color=green][color=darkred]
                        > > >>> def foo():[/color]
                        > > ... x = [3]
                        > > ... def bar():
                        > > ... x[0] += 1
                        > > (...)
                        > >
                        > > This is actually one of my biggest complaints about Python. I'd like
                        > > syntactic disambiguation between definition and assignment in order to
                        > > have control over which scope you're assigning into.[/color]
                        >
                        > Maybe Python could be changed to let 'foo.x' inside function foo mean
                        > the x variable in foo?[/color]

                        But the x variable does not live on the foo function object, it lives on
                        the stack frame created by the current call to foo.

                        So something more indirect, like scope(foo).x, would make more sense,
                        where scope() inspects the call stack looking for calls to foo and
                        returns an object with appropriate __getattr__ and __setattr__ methods.
                        This may be implementable now, by someone who knows more about python
                        introspection than I do. I tried doing it with inspect.stack, but it
                        doesn't work -- I can find the right frame and get it's f_locals
                        dictionary, but this gives read-only access to the true frame's locals.

                        --
                        David Eppstein http://www.ics.uci.edu/~eppstein/
                        Univ. of California, Irvine, School of Information & Computer Science

                        Comment

                        Working...