Welcome, guest | Sign In | My Account | Store | Cart

The logic of the code is a rewrite of http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/408937, however partial is used here and default Exception class is added when no input is given. I have also made some modifications in the way handlers and exception classes are passed to the decorator. (it was earlier posted in comments for the same receipe)

Python, 49 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import functools
def ExpHandler(*pargs):
    """ An exception handling idiom using decorators"""

    def wrapper(f):
        if pargs:
            (handler,li) = pargs
            t = [(ex, handler)
                 for ex in li ]
            t.reverse()
        else:
            t = [(Exception,None)]

        def newfunc(t,*args, **kwargs):
            ex, handler = t[0]

            try:
                if len(t) == 1:
                    f(*args, **kwargs)
                else:
                    newfunc(t[1:],*args,**kwargs)
            except ex,e:
                if handler:
                    handler(e)
                else:
                    print e.__class__.__name__, ':', e

        return functools.partial(newfunc,t)
    return wrapper
def myhandler(e):
    print 'Caught exception!', e

# Examples
# Specify exceptions in order, first one is handled first
# last one last.

@ExpHandler(myhandler,(ZeroDivisionError,))
@ExpHandler(None,(AttributeError, ValueError))
def f1():
    1/0

@ExpHandler()
def f3(*pargs):
    l = pargs
    return l.index(10)

if __name__=="__main__":
    f1()
    f3()

1 comment

Calvin Spealman 14 years, 9 months ago  # | flag

I've done something similar. I built a very complete wrapper around Twisted deferreds that uses decorators in such a fashion to define handlers and such in the same structure as synchronous code, but mapping it to asynchronous handlers through Twisted deferreds.

http://cheeseshop.python.org/pypi/DeferArgs