Ian Bicking: the old part of his blog

Re: More on Python Metaprogramming

That limit is what descriptors can do, and basically descriptors can respond to attribute access. They can't tell the class that they exist (until someone tries to access them)

I don't understand what you mean by that. Classes (and even instances) can certainly know that a descriptor exists in its own dict, like any other attribute.

...they never know what attribute name they are bound to

Unless they are told what name they are bound to, which is easy enough to do in the constructor. In the case when you define a descriptor in the class body, you can use a metaclass to tell the descriptor what name it's bound to, and skip repeating the name.

...and they don't know what class they are bound to until they are accessed.

Again, unless they are told, which is easy enough.

In ORMs this causes some problems, because classes really want to know what columns they have, and columns want to know what name they were given.

In Dejavu*, I got around the second issue (column names) by giving each descriptor a "key" attribute, which is either provided in the constructor or (more commonly) by the metaclass. I got around the first issue by storing a _properties dict in the owner class, of the form: {descriptor.key: instance_value}. Each instance makes a copy of that dict for itself. In this way, both the owner class and its instances know which of their attributes are UnitProperty descriptors.

Comment on More on Python Metaprogramming
by Robert Brewer

Comments:

I don't understand what you mean by that. Classes (and even instances) can certainly know that a descriptor exists in its own dict, like any other attribute.

The point is that the class has to do some extra stuff to find the attribute, where ActiveRecord/Ruby's technique doesn't require anything special in the class. You can't know that a column object exists until you search your __dict__. And follow MRO, for that matter.

I do explain right after this how you can make a class look for these things, and give attributes access to some of that extra information. I'd like for this to become a natural idiom in Python, not viewed as special magic. So I'd like a consistent set of practices, which doesn't presuppose what kind of object you are looking for (i.e., doesn't involve looking for all column attributes).

# Ian Bicking