[Python-ideas] Multiple arguments for decorators

Nick Coghlan ncoghlan at gmail.com
Tue Dec 1 04:56:17 EST 2015


On 1 December 2015 at 12:52, Andrew Barnert via Python-ideas
<python-ideas at python.org> wrote:
> It seems a lot cleaner to just pass a class to the decorator:
>
> class Property:
>     def __init__(self, cls):
>         self.fget = getattr(cls, 'fget', None)
>         self.fset = getattr(cls, 'fset', None)
>         self.fdel = getattr(cls, 'fdel', None)
>         self.doc = getattr(cls, '__doc__', None)
>         # everything below this point is exactly the same as the
>         # existing implementation in the descriptor HOWTO (or
>         # the C implementation in descrobject.c).
>
> class Foo:
>     def __init__(self):
>         self._x = 42
>     @Property
>     class x:
>         def fget(self):
>             return self._x
>         def fset(self, value):
>             self._x = value
>         def fdel(self):
>             del self._x

I'm not following this discussion closely, but saw a reference to "Why
not just use a class?" in one of the later posts, and hence went
looking for the specific post suggesting that (since it's a question
with a specific-but-not-obvious answer).

A class based approach like the one suggested here came up in the
previous discussion that gave us the current syntax:

    class Foo:
        def __init__(self):
            self._x = 42
        @property
        def x(self):
            return self._x
        @x.setter
        def x(self, value):
            self._x = value
        @x.deleter
        def x(self):
            del self._x

The main objection I recall being raised against the class based
approach in that previous discussion is that it handles the "self"
reference in the property implementation methods in a confusing way:
the "self" refers to an instance of the class containing the property
definition, *not* to an instance of the class containing the methods.
By contrast, when you use the "property/setter/deleter" pattern or the
original non-decorator based pattern, all of the individual methods
are written as normal methods, with the "self" referring to an
instance of the class that contains the method definition as usual.
Any approach based on defining a new indented suite has the same
problem (in that it makes it harder for a human reader to figure out
the correct referent for the "self" parameters), but using a class
statement specifically has the problem of "no, not *this* class,
*that* class".

Beyond that, property and any similar decorators are really just a
special case of a higher order function accepting multiple distinct
functions as inputs, and Python's syntax generally isn't structured to
make that easy to do.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-ideas mailing list