The current grammar for decorators is
decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE
This restricts the decorator syntax to dotted names with an optional call with an argument list:
@spam.eggsdef f(): ... @ham('foo, 'bar')def g(): ...
I love the amount of generality and abstraction in Python, but I think this is a place where there could be more of that: I think arbitrary expressions should be allowed; the value of that expression is what gets used as the decorator, using its *call* method (raising TypeError if the object is not callable). This would allow things like:
@(lambda x: x)def f(): ...
(this currently raises a SyntaxError).
Note that I didn’t come up with this because I have a particular application in mind, it just irks me that this isn’t possible in Python :-) ! Here is a perhaps slightly more stimulating example:
@(lambda factory: factory())def foo(): # this is a one-use factory for real_foo call_count = 0 # essentially a static variable
def real_foo(): nonlocal call_count call_count += 1 return call_count
This is more a “purity” thing than a “practicality” thing, but I don’t think it has any negative effects on practicality or on the usual use of decorators.