On 5 Apr 2005 00:54:25 -0700, "Kay Schluehr" <[EMAIL PROTECTED]> wrote:
>Steve Holden wrote: > >> You have several times mentioned the possibility of a decorator >taking >> more than one argument, but in my understanding of decorators this >just >> wouldn't make sense. A decorator should (shouldn't it) take precisely > >> one argument (a function or a method) and return precisely one value >(a >> decorated function or method). > I agree from an English language point of view. I.e., a verber is something that does the verbing, so a decorator ought to be the thing that does the decorating, which is the function/callable(s) resulting on stack from the evaluation of the @-line. In the case of a single @deco name, the evaluation is trivial, and the difference between the @-expression and the resulting callable might be overlooked. Full-fledged general expressions after the '@' are for some reason disallowed, but it is handy to allow attribute access and calling in the syntax, so the relevant Grammar rules are: >From the 2.4 Grammar, the key part seems to be decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE decorators: decorator+ funcdef: [decorators] 'def' NAME parameters ':' suite and further on dotted_name: NAME ('.' NAME)* So the Python Grammar's name for the @-expression is just plain "decorator" which conflicts with my English-based reading of the word ;-/ So it appears the intent is to call the entire @-line the "decorator" and I guess to have a name for what evaluating the @-line returns on the stack, we could call it the "decorating callable" since it is what takes the function parameter as its first parameter and decorates the function and returns the decorated function. But I don't like it, English-wise. I would rather call the @-line the "decorator expression" and what it evaluates to the "decorator." Can we change the grammar with s/decorator/decorator_expr/ ? >Yes. I think this sould be fixed into the minds of the people exacly >this way You state it: I think we may be agreeing in principle but with different words ;-) > >When writing > >@decorator(x,y) >def f(): > .... > >not the so called "decorator" function but decorator(x,y) is the ^--(the result of evaluating) >decorating function and decorator(x,y) is nothing but a callable object ^--(the result of evaluating) >that takes f as parameter. A little correcture of Your statement: it is >NOT nessacary that a function or method will be returned from a >decorator. Yes, in fact it could even perversely be colluding with a known succeeding decorator callable to pass info strangely, doing strange things, e.g., >>> trick = ['spam', 'eggs'] >>> def choose_name(tup): ... nx, f = tup ... f.func_name = trick[nx] ... return f ... >>> def namedeco(nx=1): ... return lambda f, nx=nx:(nx, f) ... >>> @choose_name ... @namedeco() ... def foo(): pass ... >>> foo <function eggs at 0x02EE8E64> >>> @choose_name ... @namedeco(0) ... def foo(): pass ... >>> foo <function spam at 0x02EE8DF4> I.e., namedeco evaluates to the lambda as decorator function, and that passes a perverse (nx, f) tuple on to choose_name, instead of a normal f. > >def decorator(x,y): > def inner(func): > return x+y > return inner > >@decorator(1,2) >def f():pass > >>>> f >3 > >This is perfectly valid allthough not very usefull ;) > Perhaps even less useful, the final decorator can return something arbitrary, as only the name in the def matters at that point in the execution (as a binding target name), so: >>> def dumbdeco(f): return 'something dumb' ... >>> @dumbdeco ... def foo(): pass ... >>> foo 'something dumb' Hm, maybe some use ... >>> def keydeco(name): ... return lambda f: (name, f) ... >>> @keydeco('pooh_foo') ... def foo(): pass ... >>> @keydeco('tigger_bar') ... def bar(): pass ... >>> dict([foo, bar]) {'pooh_foo': <function foo at 0x02EE8DBC>, 'tigger_bar': <function bar at 0x02EE8DF4>} ... nah ;-) Anyway, I think a different name for what comes after the "@" and the callable that that (very limited) expression is supposed to return would clarify things. My conceptual model is @decorator_expression # => decorator def decorating_target(...): ... Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list