Uplevel functionality

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

    Uplevel functionality

    Hello,

    I would like to know if there is any possibility in Python to execute
    arbitrary scripts in the context higher in the stack frame.

    In essence, I would like to have the equivalent of the following Tcl code:

    proc repeat {n script} {
    for {set i 0} {$i < $n} {incr i} {
    uplevel $script
    }
    }

    This allows me to do:

    repeat 5 {puts "hello"}

    prints:
    hello
    hello
    hello
    hello
    hello

    Or this:

    set i 10
    repeat 5 {incr i}
    puts $i

    prints:
    15

    That second example shows that the script provided as a second parameter
    to the "repeat" procedure (the script is "incr i") is executed in the
    context where the procedure was called, not locally in the procedure itself.

    The strongest analogy to the above repeat procedure in Tcl would be a
    hypothetical Python function:

    def repeat(n, script):
    for i in xrange(n):
    EVALUATE script HIGHER IN THE STACK #???


    Thank you very much,

    --
    Maciej Sobczak : http://www.msobczak.com/
    Programming : http://www.msobczak.com/prog/

  • Robin Becker

    #2
    Re: Uplevel functionality

    In article <bsu3bu$5rm$1@n emesis.news.tpi .pl>, Maciej Sobczak
    <no.spam@no.spa m.com> writes

    How about this, apparently f_locals/globals are readonly so you won't be
    allowed arbitrary scopes.

    ############### #############
    C:\tmp>cat repeat.py
    def repeat(n, script):
    from sys import _getframe
    f = _getframe(1)
    L = f.f_locals
    G = f.f_globals
    for i in xrange(n):
    exec script in G, L

    def test():
    i = 0
    repeat(3,'print i;i+=5')

    if __name__=='__ma in__':
    test()

    C:\tmp>repeat.p y
    0
    5
    10

    C:\tmp>
    ############### #############[color=blue]
    >Hello,
    >
    >I would like to know if there is any possibility in Python to execute
    >arbitrary scripts in the context higher in the stack frame.
    >
    >In essence, I would like to have the equivalent of the following Tcl code:
    >
    >proc repeat {n script} {
    > for {set i 0} {$i < $n} {incr i} {
    > uplevel $script
    > }
    >}
    >
    >This allows me to do:
    >
    >repeat 5 {puts "hello"}
    >
    >prints:
    >hello
    >hello
    >hello
    >hello
    >hello
    >
    >Or this:
    >
    >set i 10
    >repeat 5 {incr i}
    >puts $i
    >
    >prints:
    >15
    >
    >That second example shows that the script provided as a second parameter
    >to the "repeat" procedure (the script is "incr i") is executed in the
    >context where the procedure was called, not locally in the procedure itself.
    >
    >The strongest analogy to the above repeat procedure in Tcl would be a
    >hypothetical Python function:
    >
    >def repeat(n, script):
    > for i in xrange(n):
    > EVALUATE script HIGHER IN THE STACK #???
    >
    >
    >Thank you very much,
    >[/color]

    --
    Robin Becker

    Comment

    • Robin Becker

      #3
      Re: Uplevel functionality

      In article <X6LEpKAqFu8$Ew ln@jessikat.fsn et.co.uk>, Robin Becker
      <robin@jessikat .fsnet.co.uk> writes

      However, by using an exec '' the following can be made to work. The exec
      is used to disable the unwanted optimisation of print k into a name
      error.

      ############### ############### ####
      def repeat(n, script):
      from sys import _getframe
      f = _getframe(1)
      L = f.f_locals
      G = f.f_globals
      for i in xrange(n):
      exec script in G, L

      def test():
      i = 0
      repeat(3,'print i;i+=5')
      exec ''
      repeat(3,'k=2')
      print k

      if __name__=='__ma in__':
      test()
      ############### ############### ####[color=blue]
      >In article <bsu3bu$5rm$1@n emesis.news.tpi .pl>, Maciej Sobczak
      ><no.spam@no.sp am.com> writes
      >
      >How about this, apparently f_locals/globals are readonly so you won't be
      >allowed arbitrary scopes.
      >
      >############## ##############
      >C:\tmp>cat repeat.py
      >def repeat(n, script):
      > from sys import _getframe
      > f = _getframe(1)
      > L = f.f_locals
      > G = f.f_globals
      > for i in xrange(n):
      > exec script in G, L
      >
      >def test():
      > i = 0
      > repeat(3,'print i;i+=5')
      >
      >if __name__=='__ma in__':
      > test()
      >
      >C:\tmp>repeat. py
      >0
      >5
      >10
      >
      >C:\tmp>
      >############## ##############[color=green]
      >>Hello,
      >>
      >>I would like to know if there is any possibility in Python to execute
      >>arbitrary scripts in the context higher in the stack frame.
      >>
      >>In essence, I would like to have the equivalent of the following Tcl code:
      >>
      >>proc repeat {n script} {
      >> for {set i 0} {$i < $n} {incr i} {
      >> uplevel $script
      >> }
      >>}
      >>
      >>This allows me to do:
      >>
      >>repeat 5 {puts "hello"}
      >>
      >>prints:
      >>hello
      >>hello
      >>hello
      >>hello
      >>hello
      >>
      >>Or this:
      >>
      >>set i 10
      >>repeat 5 {incr i}
      >>puts $i
      >>
      >>prints:
      >>15
      >>
      >>That second example shows that the script provided as a second parameter
      >>to the "repeat" procedure (the script is "incr i") is executed in the
      >>context where the procedure was called, not locally in the procedure itself.
      >>
      >>The strongest analogy to the above repeat procedure in Tcl would be a
      >>hypothetica l Python function:
      >>
      >>def repeat(n, script):
      >> for i in xrange(n):
      >> EVALUATE script HIGHER IN THE STACK #???
      >>
      >>
      >>Thank you very much,
      >>[/color]
      >[/color]

      --
      Robin Becker

      Comment

      • Levente Sandor

        #4
        Re: Uplevel functionality

        Maciej Sobczak <no.spam@no.spa m.com> wrote in message news:<bsu3bu$5r m$1@nemesis.new s.tpi.pl>...[color=blue]
        > Hello,
        >
        > I would like to know if there is any possibility in Python to execute
        > arbitrary scripts in the context higher in the stack frame.
        >
        > In essence, I would like to have the equivalent of the following Tcl code:
        >
        > proc repeat {n script} {
        > for {set i 0} {$i < $n} {incr i} {
        > uplevel $script
        > }
        > }
        >
        > This allows me to do:
        >
        > repeat 5 {puts "hello"}
        >
        > prints:
        > hello
        > hello
        > hello
        > hello
        > hello
        >
        > Or this:
        >
        > set i 10
        > repeat 5 {incr i}
        > puts $i
        >
        > prints:
        > 15
        >
        > That second example shows that the script provided as a second parameter
        > to the "repeat" procedure (the script is "incr i") is executed in the
        > context where the procedure was called, not locally in the procedure itself.
        >
        > The strongest analogy to the above repeat procedure in Tcl would be a
        > hypothetical Python function:
        >
        > def repeat(n, script):
        > for i in xrange(n):
        > EVALUATE script HIGHER IN THE STACK #???
        >[/color]

        Yes, it would be

        def repeat(n, script):
        for i in xrange(n):
        exec(script, locals(), globals())

        repeat(5, 'print "hello"')

        i = 10
        repeat(5, 'i += 1')
        print i

        [color=blue]
        >
        > Thank you very much,[/color]

        With pleasure,
        ----
        levi

        Comment

        • Terry Reedy

          #5
          Re: Uplevel functionality


          "Maciej Sobczak" <no.spam@no.spa m.com> wrote in message
          news:bsu3bu$5rm $1@nemesis.news .tpi.pl...[color=blue]
          > Hello,
          >
          > I would like to know if there is any possibility in Python to execute
          > arbitrary scripts in the context higher in the stack frame.[/color]

          An alternate answer from those already posted is to not create the new
          context that you want to uplevel from. Seriously.
          [color=blue]
          > In essence, I would like to have the equivalent of the following Tcl[/color]
          code:[color=blue]
          >
          > proc repeat {n script} {
          > for {set i 0} {$i < $n} {incr i} {
          > uplevel $script
          > }
          > }[/color]

          As I read this, this defines the repeat function as an abbreviation of a
          'for' loop. The uplevel is only needed because the abbreviating process
          creates a nested frame. In Lisp, repeat would be written a text macro
          which does the substitution in the same frame, and hence the frame problem
          and need for uplevel would not arise. In Python, we currently live without
          the pluses and minuses of macros and usually write out the for loops ;-)
          [color=blue]
          > This allows me to do:
          >
          > repeat 5 {puts "hello"}
          >
          > prints:
          > hello
          > hello
          > hello
          > hello
          > hello[/color]

          for i in range(5): print 'hello' # does same thing.
          repeat(5, "print 'hello'") # even if possible, saves all of 5 key
          strokes
          repeat(5, lambda: print 'hello') # possible, without uplevel, takes 2 more
          [color=blue]
          > Or this:
          >
          > set i 10
          > repeat 5 {incr i}
          > puts $i
          >
          > prints:
          > 15[/color]

          i=10
          for n in range(5): i+=1
          print i

          In batch mode, which requires 'print ', 36 instead of 33 keystrokes.

          You *can* do this in current Python:

          def repeat(num, func):
          for i in range(num): func()

          def inci(): i[0]+=1 # need def since lambda only abbreviates 'return
          expression'

          i=[10]
          repeat(5, inci)[color=blue][color=green][color=darkred]
          >>> print i[0][/color][/color][/color]
          15

          Python goes for clarity rather than minimal keystrokes. Example:
          It has been proposed that 'for i in n:' be equivalent to 'for i in
          range(n):'.
          Given the set theory definition n == {0, ..., n-1} (==set(range(n) )),
          this is theoretically sensible, but was judged too esoteric for most
          people.

          Terry J. Reedy


          Comment

          • Christos TZOTZIOY Georgiou

            #6
            Re: Uplevel functionality

            On Wed, 31 Dec 2003 12:41:02 -0500, rumours say that "Terry Reedy"
            <tjreedy@udel.e du> might have written:
            [color=blue][color=green]
            >> This allows me to do:
            >>
            >> repeat 5 {puts "hello"}
            >>
            >> prints:
            >> hello
            >> hello
            >> hello
            >> hello
            >> hello[/color]
            >
            >for i in range(5): print 'hello' # does same thing.
            >repeat(5, "print 'hello'") # even if possible, saves all of 5 key
            >strokes
            >repeat(5, lambda: print 'hello') # possible, without uplevel, takes 2 more[/color]

            print is invalid in a lambda (like other statements) as you most surely
            know. I would guess the champagne is to blame? :-) Happy new year!
            --
            TZOTZIOY, I speak England very best,
            Ils sont fous ces Redmontains! --Harddix

            Comment

            Working...