On Mar 24, 9:48 am, Jason <[EMAIL PROTECTED]> wrote: > On Mar 24, 5:21 am, Julien <[EMAIL PROTECTED]> 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. -- http://mail.python.org/mailman/listinfo/python-list