[Python-ideas] A user story concerning things knowing their own names
Robert Kern
robert.kern at gmail.com
Wed Mar 16 19:47:45 CET 2011
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
The alternative is to only provide factories such that you always get a new
descriptor:
ColorTrait = lambda: Trait("black", Tuple, List, Str, color_table)
class Figure(HasTraits):
background = ColorTrait()
foreground = ColorTrait()
However, this makes these new descriptors inconsistent with current descriptors,
which can be shared between classes. It also prevents you from passing around
descriptor objects as first-class citizens. For example, I might want to ask the
ColorTrait for its constituents in order to construct a new one that has a
different default value. I can't ask that of a factory function.
This objection holds for any proposal that requires the descriptor object itself
to hold onto its name, no matter how it acquires that name. Personally, I don't
want descriptors that know their own name; I want descriptors that can be told
what name to use for each operation.
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
More information about the Python-ideas
mailing list