[Python-ideas] Assignment decorators (Re: The Descriptor Protocol...)

Guido van Rossum guido at python.org
Fri Mar 4 03:00:30 CET 2011


On Thu, Mar 3, 2011 at 5:40 PM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Guido van Rossum wrote:
>
>> Greg, what is your use case for passing the lhs name into the
>> function?
>
> I've found two so far:
>
> * Named tuples
> * OverridableProperty instances in PyGUI

So a metaclass doesn't work for the latter?

>> Also it seems that one couldn't decorate all but the simplest assignments:
>>
>> @dec
>> lhs.attr = rhs
>> # lhs.attr = dec('lhs.attr', rhs)  ???
>
> That would be disallowed -- the target would be restricted to
> a bare name. This is no worse than the corresponding restriction
> for 'def' and 'class'.

It is worse, because undecorated function and class definitions also
have that restriction; but undecorated assignments don't. Though I
suppose I could live with it because I don't see the use cases.

>> The use case I can think of for the first example would be to declare
>> fields in a model class that know their own field name
>
>> ... the @decorator syntax has the
>> disadvantage of requiring at least two lines per field, whereas the
>> current solution requires only one line
>
> Yes, that's a valid criticism. The 'def' version would address it.
>
>> But that use case is
>> covered pretty well by metaclasses,
>
> I'm not convinced that metaclasses are a general solution to this
> kind of problem.

It's indeed not for the namedtuple case. I think it can work for PyGUI
but I don't know much about it.

> I had an interesting experience recently with SqlAlchemy, where there
> is a Table class having a metaclass that does magical things with the
> contents of the class dict when the class is created. It turns out
> you can't subclass the Table class using the normal Python techniques,
> because the metaclass magic gets triggered too soon. To work around
> this they provide a flag you can use to suppress the magic, but it's
> an ugly kludge.

Hm. Maybe that's because their metaclass has some other side effects
that has nothing to do with the property definition patchup? The
examples of using metaclasses for field/property definitions that I'm
familiar with (in Django and App Engine) are both fine with
subclassing.

> There's also the problem that you can only use *one* metaclass at
> a time, so if you want a class that makes use of features provided
> by two different metaclasses, you're out of luck. For example, if
> I were relying on a metaclass to set up my OverridableProperty
> descriptors, and I wanted a Django model class to have some of
> those properties, I wouldn't be able to do it, because the
> metaclasses would conflict.

With enough patience you can actually combine metaclasses using
multiple inheritance. The book I used to guide my way through
metaclasses (http://www.amazon.com/Putting-Metaclasses-Work-Ira-Forman/dp/0201433052)
even automatically constructed the combined metaclass (they use C++);
in Python you have to work at it a little harder, but the same
approach can be used.

However I've never come across this, and I would surely prefer to
avoid it if possible.

I guess you need to enlighten me more about OverridableProperty;
apparently (like namedtuple) it is a pretty generic thing? I know you
are not really after saving the keystrokes but more after the DRY
principle, but ISTM that passing the name in as a string literal seems
a pretty small price to pay for the benefit derived, and the cost of
getting the assignment decorator designed, implemented and documented
seems pretty high.

-- 
--Guido van Rossum (python.org/~guido)



More information about the Python-ideas mailing list