Adding a list of descriptors to a class

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Mon Aug 6 02:26:49 EDT 2007


Bob B. a écrit :
> 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"
> 
> Any ideas?

Steven already show you the simplest solution. Now if you want something 
"cleaner" (or at least more transparent to persons subclassing MyClass - 
which may or may not be a concern), you can use metaclasses too:

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"
         if obj is None:
             return self
         return self.value

class MyType(type):
     def __init__(cls, name, bases, dic):
         attributes = dic.get('attributes', None)
         if attributes is not None:
             for attrname, initval in attributes.iteritems():
                 setattr(cls, attrname, MyDesc(attrname, initval))

class MyClass(object):
     __metaclass__ = MyType
     attributes = dict(attr1="attr1", attr2="attr2")

class MySubclass(MyClass):
     # let you override parent's attributes...
     attributes = dict(attr1="otherattr1", attr3="a new one")


HTH



More information about the Python-list mailing list