properties + types, implementing meta-class desciptors elegantly?
Mike C. Fletcher
mcfletch at rogers.com
Sun Jul 20 00:36:23 CEST 2003
Okay, rather than respond to the fragments first, which just seems to be
confusing people, as they aren't getting the previous discussion.
Here's a quick sketch of what I'm creating:
class Meta( type ):
tableName = common.StringProperty(
"tableName", """The table in which this class stores it's primary
defaultValue = "",
implementationBase = common.ClassByNameProperty(
"implementation", """Base class for implementation""",
defaultValue = "wxpytable.dbresultset.DBResultSet",
setDefaultOnGet = 0,
Now, those objects from "common" are part of a fairly involved hierarchy
of descriptor classes which provide type coercion, default-value
retrieval, automated lookup of factory functions, managed list-of-type
support, and a dozen other features. Here's the framework of what a
* hooks the __set__ event (and __get__ and __delete__)
o is thereby a descriptor
o can be introspected from the object with the properties
+ has documentation
+ has meta-data for coercion, type-checking, default
values, operations for choosing common values,
+ can be readily sub-classed to produce new effects,
such as using weak references or storing values in a
database based on schema objects, or calling methods
on a client...
* checks the data type of the value
o if necessary, coerces the value (normally defering to the
"baseType" for the property)
* finally, stores the value
o tries to do what would have been done if there were no
descriptor (with the new, coerced value)
o does *not* create new names in the object's namespace (all
names are documented w/ descriptors, there's not a lot of
'_' prefixed names cluttering the namespace)
o does *not* require a new dictionary/storage-object attribute
for the object (the descriptor works like any other
descriptor, a *stand-alone* object that replaces a regular
It's that last part that I'd like to have a function/method to
accomplish. That is, store (and obviously retrieve as well) attribute
values for objects, instances, types, classes, __slot__'d instances,
etceteras under a given name without triggering any of the __setattr__
machinery which defers to the __set__ method of the associated descriptor.
I can work around the problem by violating either of those two bullet
points under "finally, stores the value", but I'm looking for something
that *doesn't* violate them. See below for responses to particular
Bengt Richter wrote:
> client.__dict__['v'] = value
>the above line should work for this example, so it must be different from
>what you were doing before? Perhaps the client object before was a class?
>I guess I'm not getting the big picture yet of your design intent.
That's what the base properties do, but they just can't work when doing
a meta-class, as it's __dict__ is a dict-proxy, which doesn't allow
assignment. I'm looking for a method to tell the Python system "Okay,
what would you have done if there were no descriptors? Here's the key
and value to set, go set them." That sample was just to demonstrate why
calling object.__setattr__ wouldn't work (it recursively calls the
>Are you trying to make a base class that has properties that can
>set same-named properties in the subclass via attributes
>of objects instantiated from the subclass? Or as attributes of the
>subclass? Do you need the property ability to munge its arguments dynamically?
>Otherwise a plain old attribute assignment to the subclass per se should install
>the property for its instances, no?
Nope, I'm trying to make meta-classes which have rich properties. The
particular project is a plug-in system, where the classes (the
metaclass-instances) want to have all sorts of rich metadata associated
with them in a way which meshes with the rest of the system (i.e. using
a descriptor-based introspection mechanism).
Mike C. Fletcher
Designer, VR Plumber, Coder
More information about the Python-list