> If you passed an object that has several methods to call (using tuple > or list) and you want to handle several softexceptions and ignore some > others, you must still pass an empty methods to the one you want to > ignore, cluttering the caller's code by significant degree: > > def somefunc(a, b, callback = (DO_NOTHING, DO_NOTHING, DO_NOTHING, > DO_NOTHING)): > if a == 0: raise callback(0) > try: > a += b > except ZeroDivisionError: > raise callback(1) > if a <= 0: raise callback(2) > raise callback(3) > return a > > somefunc(a, b, (callbackzero, DO_NOTHING, callbacktwo, > DO_NOTHING))
You misunderstood. I'd pass something like a context-object, which wold look like this: def somefunc(a, b, context=NullContext()): if a == b: context.a_equals_b() .... Not more clutter than with only one callback. And the NullContext-object would actually serve as documentation on what events the code produces. >> def toplelevel(): >> def callback(a, b): >> if a == b: >> raise InterruptException() >> try: >> work(callback) >> except InterruptException: >> pass >> >> def work(callback=callback): >> a = 10 >> b = 20 >> callback(a, b) > > That's why I said most things that can be more cleanly handled by > SoftException can usually be handled in other forms, although in a > more cluttered way. > > That could be more cleanly written in SoftException as: > def work(): > a = 10 > b = 20 > raise Equal(a, b) > > def toplevel(): > try: > work() > except Equal, args: > a, b = args > if a == b: > raise InterruptException I totally fail to see where raise Equal(a, b) is less cluttered or not than callback(a, b) Actually, the latter is even less cluttered, misses a raise - if pure number of literals is your metric, that is. > If there is a syntax support, you could also make "resume" able to > transfer values: > > def somefunc(a, b): > if a == b: a, b = raise Equal(a, b) > > def toplevel(): > try: > somefunc(10, 20) > except Equal, args: > a, b = args[0], args[1] + 1 > resume a, b Sure, you can make all kinds of things, but so far you didn't come up with a comprehensive feature description that just _does_ specify what SEs are and what not. > Perhaps you meant: > raise_soft(SoftException) > > cause SoftException() may have side effects if called greedily Nope, I didn't, and it's beside the point. > That could be done, but when raise_soft() returns, it returns to the > code that raises it so it must be 'break'en: > > def caller(a, b): > if a == b: > raise_soft(SoftException) > break > > but this makes SoftException must break everytime, which make it lost > its original purpose, so you have to add return code to raise_soft > whether you want to break it or not: You didn't understand my example. If there is a handler registered, it will be invoked. If not, nothing will be raised. The exact same amount of state-keeping and lookups needs to be done by the SE-implementation. > That could be done, but when raise_soft() returns, it returns to the > code that raises it so it must be 'break'en: > def caller(a, b): > if a == b: > if raise_soft(SoftException): > break > > Compare to: > def caller(a, b): > if a == b: > raise SoftException > > And this also makes it impossible to have state-changing behavior > without some other weirder tricks That's not true. The with add_soft_handler(SoftException, handler): approach (I missed the handrel the first time, sorry) can easily throw an exception to interrupt, like this: def handler(e): if some_condition_on_e(e): raise InterruptException() with add_soft_handler(SoftException, handler): try: work(...) except InterruptException: pass You could also introduce a function def interruptable(fun, *args, **kwargs): try: return fun(*args, **kwargs) except InterruptException: pass to make the code look a bit cleaner - if it fits your usecase, that is of course. I don't say that SoftExceptions can't have semantics that go beyond this. I just don't see a oh-so-compelling use-case that makes things so much better than they are reachable now, without actually much programming. Diez -- http://mail.python.org/mailman/listinfo/python-list