Dynamically Cause A Function To Return

Arnaud Delobelle arnodel at gmail.com
Tue Sep 20 21:04:29 CEST 2011


On 20 September 2011 00:13, Jordan Evans <mindwalkernine at gmail.com> wrote:
> I want dynamically place the 'return' statement in a function via user input
> or achieve the same through some other means.  If some other means, the user
> must be able initiate this at runtime during a raw_input().  This is what I
> have so far, this would be an awesome command line debugging tool if I can
> get it to work.
>
> def b(label="", *args):
>     """Used to create breaks for debugging.  Will break the function or
> continue the function it is place within based on user input.  Has as a
> input loop for querying variables and executing code before a break or a
> continue."""
>     print label+":",
>     for arg in args:
>         print str(arg),
>     if len(args):
>         print
>     x = ""
>     while x != ".":
>         command = raw_input()
>         try:
>             exec command
>         except:
>             pass
>

I don't really understand your dynamic return idea, but this reminds
me of some debugging function I wrote some time ago.  It pauses
execution and you can evaluate expression in the current stack frame
and any of its parents using the following syntax:

    <expr> executes <expr> in the stack frame where pause() was inserted
    .<expr> executes it in the parent of this stack frame
    ..<expr> in the grandparent (etc...)

    ? shows all accessible stack frames

def pause():
    import sys, inspect, re
    f = None
    print "\n*** Entering pause mode (EOF to resume)"
    try:
        while True:
            try:
                c = raw_input('pause> ')
                if c == '?':
                    for i, fi in enumerate(inspect.stack()[1:]):
                        print ('%s File "%s", line %s, in %s' %
                               ('.'*i, fi[1], fi[2], fi[3]))
                    continue
                dots = re.match(r'\.*', c)
                back = 0
                if dots:
                    back = len(dots.group())
                f = sys._getframe(back+1)
                code_name = f.f_code.co_name
                cmd = c[back:]
                val = cmd and eval(cmd, f.f_globals, f.f_locals)
                print "(%s) %r" % (code_name, val)
            except Exception, e:
                if isinstance(e, EOFError):
                    del f
                    raise
                print "%s: %s" % (type(e).__name__, e)
    except EOFError:
        pass
    finally:
        print "\n*** Leaving pause mode"


# Simple example of 'pause' in action:

>>> def g(x):
...     b = 5
...     pause()
...
>>> def f(x, y):
...     z = 2
...     g(x)
...     print "And we carry on..."
...
>>> f('spam', [4, 2])

*** Entering pause mode (EOF to resume)
pause> ?
 File "<stdin>", line 3, in g
. File "<stdin>", line 3, in f
.. File "<stdin>", line 1, in <module>
pause> b
(g) 5
pause> b+1
(g) 6
pause> .z
(f) 2
pause> .y
(f) [4, 2]
pause> .x
(f) 'spam'
pause> ..len
(<module>) <built-in function len>
pause> ^D
*** Leaving pause mode
And we carry on...
>>>

-- 
Arnaud



More information about the Python-list mailing list