<br><br><div class="gmail_quote">On Wed, Mar 16, 2011 at 1:47 PM, Robert Kern <span dir="ltr"><<a href="mailto:robert.kern@gmail.com">robert.kern@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="im">On 3/16/11 12:13 PM, Ian Bicking wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I'll note this general problem is also present in any of the declarative ORMs,<br>
which use silly hacks to tell descriptors their name.  Like you have:<br>
<br>
class Table(ORM):<br>
     name = StringColumn()<br>
<br>
Another case where I've noticed a problem is any kind of descriptor that needs<br>
its own storage; the name of the property gives a possible stable namespace for<br>
the value, but without the name you either have to pass in a name or the storage<br>
area becomes volatile.  For instance, a read-only descriptor:<br>
<a href="http://svn.colorstudy.com/home/ianb/recipes/setonce.py" target="_blank">http://svn.colorstudy.com/home/ianb/recipes/setonce.py</a><br>
<br>
You can solve this in, e.g., the ORM class by doing things when a class is<br>
created -- but it requires very specific cooperation between the class and the<br>
descriptor.  Everyone really does it different ways.<br>
<br>
One could imagine an extension of the descriptor protocol, where on class<br>
creation you called something like attr.__addtoclass__(cls, name) (for all<br>
attributes of the class that define that method) -- which if you just want the<br>
name you'd simply save that name in your object and return self.<br>
</blockquote>
<br></div>
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.<br>


<br>
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:<br>


<br>
  ColorTrait = Trait("black", Tuple, List, Str, color_table)<br>
<br>
It would be nice to simply reuse this object everywhere:<br>
<br>
  class Figure(HasTraits):<br>
    background = ColorTrait<br>
    foreground = ColorTrait<br></blockquote><div><br>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:<br>

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

                new_value = method(cls, name)<br>                if new_value is not value:<br>                    setattr(cls, name, new_value)<br><br>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).<br>

<br>  Ian<br><br></div></div>