[Python-ideas] A user story concerning things knowing their own names

Ian Bicking ianb at colorstudy.com
Wed Mar 16 22:06:29 CET 2011


On Wed, Mar 16, 2011 at 1:47 PM, Robert Kern <robert.kern at gmail.com> wrote:

> On 3/16/11 12:13 PM, Ian Bicking wrote:
>
>> I'll note this general problem is also present in any of the declarative
>> ORMs,
>> which use silly hacks to tell descriptors their name.  Like you have:
>>
>> class Table(ORM):
>>     name = StringColumn()
>>
>> Another case where I've noticed a problem is any kind of descriptor that
>> needs
>> its own storage; the name of the property gives a possible stable
>> namespace for
>> the value, but without the name you either have to pass in a name or the
>> storage
>> area becomes volatile.  For instance, a read-only descriptor:
>> http://svn.colorstudy.com/home/ianb/recipes/setonce.py
>>
>> You can solve this in, e.g., the ORM class by doing things when a class is
>> created -- but it requires very specific cooperation between the class and
>> the
>> descriptor.  Everyone really does it different ways.
>>
>> One could imagine an extension of the descriptor protocol, where on class
>> creation you called something like attr.__addtoclass__(cls, name) (for all
>> attributes of the class that define that method) -- which if you just want
>> the
>> name you'd simply save that name in your object and return self.
>>
>
> If we were to extend the descriptor protocol, I think it would be better to
> extend it by providing __get_ex__(self, instance, owner, name),
> __set_ex__(self, instance, name, value), etc. methods that would be called
> in preference over the current __get__() and __set__() methods. This allows
> descriptor objects to be reused.
>
> We do this reasonably often with the Traits package (which overrides
> __getattribute__() to essentially implement this __get_ex__()/__set_ex__()
> protocol by different names). For example, we have a complicated trait for
> specifying colors:
>
>  ColorTrait = Trait("black", Tuple, List, Str, color_table)
>
> It would be nice to simply reuse this object everywhere:
>
>  class Figure(HasTraits):
>    background = ColorTrait
>    foreground = ColorTrait
>

As I was thinking of __addtoclass__ it would address this, though at class
instantiation time instead of attribute access time.  Specifically it would
be like there was a fixup stage that would look like:

def fixup(cls):
    for class_instance in cls.__mro__:
        for name, value in class_instance.__dict__.items():
            method = getattr(value, '__addtoclass__', None)
            if method is not None:
                new_value = method(cls, name)
                if new_value is not value:
                    setattr(cls, name, new_value)

If ColorTrait returns a new instance when __addtoclass__ is called, then it
can, and all of its instances will be class-specific (and not shared with
subclasses).

  Ian
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20110316/f6a0eea0/attachment.html>


More information about the Python-ideas mailing list