Bengt Richter wrote: > ;-) > We have Have we?
Looks like not a lot of interested takers so far. But I'll bite. ;-) <clip intro> > 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')) So far they are fairly equivalent. So there's not really any advantage over the equivalent inline function. But I think I see what you are going towards. Decorators currently must be used when a function is defined. This option attempts to makes them more dynamic so that they can be used where and when they are needed. How about if you make it optional too? if keep_log: @log_of_interesting_values b = get_value(c,d): Or... @@keeplog log_of_interesting_values # if keeplog decorate. b = get_value(c,d) Just a thought. > 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] I'm not sure I follow this one.. Well I do a little. Looks like it might be going the direction of with statements, but only applied to a single expression instead of a block or suite. > 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) Wouldn't this one work now? > [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 Interestin. When it comes to decorators, and now the with statements, I can't help but feel that there's some sort of underlying concept that would work better. It has to do with generalizing flow control in a dynamic way relative to an associated block. One thought is to be able to use a place holder in an expression list to tell a statement when to do the following block of code. I'll use 'do' here... since it's currently unused and use @@@ as the place holder. (These are *NOT* thought out that far yet, I know... just trying to show a direction that might be possible.) do f=open(filename); @@@; f.close(): # do the block where @@@ is. for line in f: print line, print And an alternate version similar to a "with" statement. try f=open(filename); @@@; finally f.close(): for line if f: print line, print Maybe the exception could be held until after the try line is complete? The place holder idea might be useful for decorating as well. But I'm not sure how the function name and arguemtns would get passed to it. do deco(@@@): def foo(): pass or maybe it would need to be... do f=@@@, deco(f): def foo() pass As I said, it still needs some thinking.. ;-) Maybe leaving off the colon would use the following line without indenting as per your example? do deco(@@@) b = 42 It doesn't quite work this way I think. Possibly having a couple of different types of place holder symbols which alter the behavior might work? do deco($$$) # $$$ intercept name binding operation? b = 42 Well, it may need to be a bit (or a lot) of changing. But the idea of controlling flow with a place holder symbol might be a way to generalize some of the concepts that have been floating around into one tool. I like the place holders because I think they make the code much more explicit and they are more flexible because you can put them where you need them. > orthogonal-musing-ly ;-) "Orthogonal is an unusual computer language in which your program flow can go sideways. In actuality in can go in just about any direction you could want." http://www.muppetlabs.com/~breadbox/orth/ ;-) Cheers, Ron > Regards, > Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list