Shortcutting the function call stack
castironpi at gmail.com
castironpi at gmail.com
Mon Mar 24 11:06:01 EDT 2008
On Mar 24, 9:48 am, Jason <tenax.racc... at gmail.com> wrote:
> On Mar 24, 5:21 am, Julien <jpha... at gmail.com> wrote:
>
>
>
>
>
> > Hello all,
>
> > I would like to do something like:
>
> > def called(arg)
> > if arg==True:
> > !!magic!!caller.return 1
>
> > def caller(arg)
> > called(arg)
> > return 2
>
> > Here, the fake !!!magic!!! represents a statement (which I ignore)
> > that would make the caller function return a value different from what
> > it'd return normally.
>
> > For example, caller(True) would return 1, and caller(False) would
> > return 2. The reason I want that is because I don't want the caller
> > function to know what's going on in the called function, and be
> > shortcut if the called function think it's necessary.
>
> > Would you know if that's possible, and if so, how?
>
> > I've done a bit of research and I think I've found some good pointers,
> > in particular using the 'inspect' library:
>
> > import inspect
>
> > def called(arg)
> > if arg==True:
> > caller_frame = inspect.stack()[1]
> > ...
>
> > Here 'caller_frame' contains the frame of the caller function. Now,
> > how can I make that frame return a particular value?
>
> > By the way, I'm not really interested in 'called' throwing an
> > exception and 'caller' catching it. In fact, I want things to remain
> > completely transparent for 'caller'.
>
> > Hope that was clear... :/
>
> > Thanks!
>
> > Julien
>
> As Steven wrote, it's not very clear. If we knew the intent of this,
> we could perhaps point you to a more useful, maintainable technique.
> We don't know why you're trying to circumvent the programming language
> in this case. Any solution that works as you described will probably
> be unportable between the different Pythons (CPython, Jython,
> IronPython, etc).
>
> Please note that the following code should work, but I've only run it
> through the interpreter in my brain. My brain's interpreter is full
> of Heisenbugs, so you may need to adjust a few things. Here's my
> thoughts:
>
> Given:
> def First( arg ):
> Second( arg )
> return 5
>
> 1) If you can modify both functions, change the first function to
> return a value in certain circumstances:
> def AltFirst( arg ):
> value = Second( arg )
> if value is not None: return value
> return 5
>
> 2) Raise an exception in Second, and catch that exception above
> First:
>
> class SecondExcept(Exception):
> def __init__(self, value):
> Exception.__init__(self, 'Spam!')
> self.value = value
>
> def Second(arg):
> if arg == my_conditional_value:
> raise SecondExcept( 5 )
>
> # The following could even be put in your own function,
> # or in a wrapper or decorator for the First function.
> try:
> myvalue = First( 'Vikings!' )
> except SecondExcept, exc:
> myvalue = exc.value
>
> When you need to use an exceptional pathway, use an exception. They
> aren't just for reporting errors.
Exceptions are a control tool. There was a 'goto using Exceptions'
once in the manuals. I don't see a problem with a local control-flow
object. It would appease a number of requests I've read.
for x:
for y:
control.break( 2 )
if a:
if b:
control.fail( 2 )
so no need to reduplicate:
else:
thing()
else:
thing()
if a:
if b:
control.mostrecenttest( 0 )
def f():
def g():
control.return( 2 )( "early" )
Something tells me generators could solve the problem, but I may be
enamored, so it's a separate post.
More information about the Python-list
mailing list