There's been a discussion in this list on extending Python to provide SYNTAX such as @decorator
name = EXPRESSION
and also suitable semantics. (Here 'name' is an identifier, in the discussion called a 'variable'.)
This post is about providing SEMANTICS for such decorator syntax. We can do this within the existing Python syntax for decorators.
Recall that
@decorator
def fn(....):
# body
is usually equivalent to
def fn(....):
# body
fn = decorator(fn)
and that decorator is just a callable that returns something. It need not return another function. It could return a 'variable', such as the result of calling fn.
Here's a proof of concept. Consider the following
BEGIN
$ cat work.py
from collections import namedtuple
Locn = namedtuple('Locn', 'doc module name')
def locn_from_fn(fn):
name = fn.__name__
module = fn.__module__
doc = fn.__doc__
return Locn(name=name, module=module, doc=doc)
def decovar(fn):
locn = locn_from_fn(fn)
return fn(locn)
@decovar
def variable(locn):
return ('value', locn)
def deconamedtuple(fn):
locn = locn_from_fn(fn)
nt = namedtuple(
locn.name, fn())
nt.__doc__ = locn.doc
nt.__module__ = locn.module
nt.__name__ =
locn.name return nt
@deconamedtuple
def Point():
'''Return a point (x, y) in the plane.'''
return 'x y'
print(variable)
print(Point)
print(Point.__doc__)
END
Here's what we get when we run the script.
BEGIN
$ python3 work.py
('value', Locn(doc=None, module='__main__', name='variable'))
<class '__main__.Point'>
Return a point (x, y) in the plane.
END
It should now be clear that this approach allows us to pass much useful information to the decorator.
I claim that this approach gives most or all of the semantic benefits of 'decorators on variables', and within the current Python syntax. If so, and the semantic benefits are strong, then here's part of a good case for extending the syntax in a future version of Python.
--
Jonathan