Adding a list of descriptors to a class

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Mon Aug 6 08:19:47 CEST 2007


Marc 'BlackJack' Rintsch a écrit :
> On Tue, 07 Aug 2007 09:25:32 -0700, Bob B. wrote:
> 
> 
>>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"
> 
> 
> Does ``setattr(self.__class__, attr, MyDesc(attr))`` work?

In the __init__() ?

Yes indeed, it works. But it means that:
1/ the attributes are not set on the class before it has been 
instanciated at least once
2/ each time you instanciate the class, the attributes are rebound to 
new MyDesc instances

class MyDesc(object):
     def __init__(self, name=None, initVal=None):
         self.name = name
         self.value = initVal
         print "new %s" % self.__class__.__name__

     def __get__(self, obj, objtype):
         # Do some stuff
         #self.value = "blah"
         if obj is None:
             return self
         return self.value

class Marc(object):
     attributes = ('toto', 'tata')
     def __init__(self):
         cls = self.__class__
         for attr in cls.attributes:
             setattr(cls, attr, MyDesc(attr, attr))

 >>> Marc.toto
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
AttributeError: type object 'Marc' has no attribute 'toto'
 >>> m1 = Marc()
new MyDesc
new MyDesc
 >>> Marc.toto
<__main__.MyDesc object at 0x4033846c>
 >>> t = _
 >>> m2 = Marc()
new MyDesc
new MyDesc
 >>> Marc.toto is t
False
 >>>

So while it "works" (kinda), I would not recommand this solution. Even 
if you do test for the existence of the attribute before rebinding it, 
you'll have to go thru the whole dance each time you instanciate the class.

My 2 cents...



More information about the Python-list mailing list