;-) We have @deco def foo(): pass as sugar (unless there's an uncaught exception in the decorator) for def foo(): pass foo = deco(foo)
The binding of a class name is similar, and class decorators would seem natural, i.e., @cdeco class Foo: pass for class Foo: pass Foo = cdeco(Foo) What is happening is we are intercepting the binding of some object and letting the decorator do something to the object before the binding occurs. So why not @deco foo = lambda:pass equivalent to foo = deco(lambda:pass) and from there, @deco <left-hand-side> = <right-hand-side> being equivalent to <left-hand-side> = deco(<right-hand-side>) e.g., @range_check(1,5) a = 42 for a = range_check(1,5)(42) or @default_value(42) b = c.e['f']('g') for b = default_value(42)(c.e['f']('g')) Hm, binding-intercept-decoration could be sugar for catching exceptions too, and passing them to the decorator, e.g., the above could be sugar for try: b = default_value(42)(c.e['f']('g')) except Exception, e: b = default_value(__exception__=e) # so decorator can check # and either return a value or just re-raise with raise [Note 1] This might be useful for plain old function decorators too, if you wanted the decorator to define the policy for substituting something if e.g. a default argument evaluation throws and exception. Thus @deco def foo(x=a/b): pass # e.g., what if b==0? as try: def foo(x=a/b): pass # e.g., what if b==0? foo = deco(foo) except Exception, e: if not deco.func_code.co_flags&0x08: raise #avoid mysterious unexpected keyword TypeError foo = deco(__exception__=e) [Note 1:] Interestingly raise doesn't seem to have to be in the same frame or down-stack, so a decorator called as above could re-raise: >>> def deco(**kw): ... print kw ... raise ... >>> try: 1/0 ... except Exception, e: deco(__exception__=e) ... {'__exception__': <exceptions.ZeroDivisionError instance at 0x02EF190C>} Traceback (most recent call last): File "<stdin>", line 2, in ? File "<stdin>", line 1, in ? ZeroDivisionError: integer division or modulo by zero orthogonal-musing-ly ;-) Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list