[Python-ideas] Decorations

Andrey Fedorov anfedorov at gmail.com
Mon Jul 13 18:36:08 CEST 2009


Hi there,

It's always bothered me that decorators require a lot of "cruft" to work.
Consider an example, from PEP-318
<http://www.python.org/dev/peps/pep-0318/>(Decorators for Functions
and Methods):

def returns(rtype):
    def check_returns(f):
        def new_f(*args, **kwds):
            result = f(*args, **kwds)
            assert isinstance(result, rtype), \
                   "return value %r does not match %s" % (result,rtype)
            return result
        new_f.func_name = f.func_name
        return new_f
    return check_returns

It seems to me everything but line 5 "assert..." is cruft. In my mind, it
makes sense to call that line the "decoration" (part of the decorator).
Since it's a decoration that's executed after the decorated function, it
makes sense to call it a post-decoration, one that may be more nicely
defined as:

@postdecoration
def returns(result, rtype):
    assert isinstance(result, rtype), "return value %r does not match %s" %
(result, rtype)

Then, `returns' can be used as in PEP-318 (but without the cruft). I've
defined similar `decoration', and `predecoration' decorators. I use the
latter for my Django views to accept POST parameters as arguments:

def filter_dict(d, fltr):
    return dict( (str(x.lower()), d[x]) for x in d if x.lower() in fltr )

@predecoration
def takesPOST(f, args):
    if len(args) == 1:
        fargs = getargspec(f).args
        get = args[0].POST
        return filter_dict(get, fargs[1:])

This way, I can define a view login(reqest, user, password) which can be
called simply from another view, without having to construct a special
`request' object.

An initial shot at the definitions is here: http://gist.github.com/146235

The design decisions I'm least confident about is the argument specs. In the
`predecoration' example, the argument `args' is a special name that
specifies the arguments passed into the decoratee, `kwargs' would be the
keyword arcgs passed into the decorateee, dec_args and dec_params being the
arguments passed into the *decorator*. This doesn't seem like an optimal
solution. The problem I'm trying to solve is "moving from a decoration which
takes no parameters to a decoration which takes parameters". For example, it
was trivial to refactor takesPOST to group POST parameters by regex passed
into the decorator. Still, I'm open to questions, ideas, opinions, etc.

What do you guys this?

Cheers,
Andrey
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20090713/6fb0d831/attachment.html>


More information about the Python-ideas mailing list