Adding a list of descriptors to a class

Steven Bethard steven.bethard at gmail.com
Tue Aug 7 12:50:10 EDT 2007


Bob B. wrote:
> I've been playing with descriptors lately.  I'm having one problem I
> can't seem to find the answer to.  I want to assign a descriptor to a
> list of attributes.  I know I should be able to add these somewhere in
> the class's __dict__, but I can't figure out where.  Here's some code:
> 
> class MyDesc(object):
>   def __init__(self, name=None, initVal=None):
>     self.name = name
>     self.value = initVal
> 
>   def __get__(self, obj, objtype):
>     // Do some stuff
>     self.value = "blah"
>     return self.value
> 
> class MyClass(object):
>   attributes = ('attr1', 'attr2')
>   for attr in attributes:
>     exec ("%s=MyDesc('%s')") % (attr, attr)
> 
>   // More stuff in the class
> 
> Ok, that "exec" is an ugly hack.  There's gotta be someway to plop
> this straight into the class's __dict__ without doing that, but when I
> try adding self.__class__.__dict__[attr] = MyDesc(attr) in MyClass's
> __init__ method, I get the error: "TypeError: 'dictproxy' object does
> not support item assignment"

Probably the simplest thing is to just add the attributes after the 
class body, e.g.::

     >>> class MyClass(object):
     ...     pass
     ...
     >>> for attr in ['attr1', 'attr2']:
     ...     setattr(MyClass, attr, MyDesc(attr))
     ...
     >>> c = MyClass()
     >>> c.attr1
     'blah'

Another option would be to use a metaclass to set the class attributes 
at class creation time::

     >>> class Meta(type):
     ...     def __init__(cls, name, bases, bodydict):
     ...         for attr in cls._desc_attrs:
     ...             setattr(cls, attr, MyDesc(attr))
     ...
     >>> class MyClass(object):
     ...     __metaclass__ = Meta
     ...     _desc_attrs = ['attr1', 'attr2']
     ...
     >>> c = MyClass()
     >>> c.attr1
     'blah'


HTH,

STeVe



More information about the Python-list mailing list