Hi
How can I make a *class* attribute read-only ?
The answer must be pretty obvious but I just can't find it (it's late and I've spent all day on metaclasses, descriptors and the like, which, as fun as it is, may have side-effects on intellectual abilities...)
*The context:*
# library code class AbstractBaseClass(object): # snip some stuff here, # a part of it depending on the derived classes # defining class attribute class_private_attrib
# client code class SubClass(AbstractBaseClass): class_private_attrib = "my private attrib" # snip
*What I'm looking for: (if possible)*
>>SubClass.class_private_attrib "my private attrib" >>SubClass.class_private_attrib = "toto" AttributeError : SubClass.class_private_attrib is read only >>s = SubClass() >>s.class_private_attribute = "toto" AttributeError : SubClass.class_private_attrib is read only
*What I've tried: (simplified as possible)*
class ReadOnlyDescriptor(object): def __init__(self, name, initval=None): self._val = initval self._name = name
def __get__(self, obj, objtype): print 'Retrieving', self._name return self._val
def __set__(self, obj, val): raise AttributeError, \ "%s.%s is ReadOnly" % (obj.__class.__.__name__, self._name)
class SubClass(object): class_private_attrib = ReadOnlyDescriptor("class_private_attrib", "my private attrib") # snip
*What i get:* >>SubClass.class_private_attrib Retrieving class_private_attrib "my private attrib" >>SubClass.class_private_attrib = "toto" >>SubClass.class_private_attrib "toto" >>SubClass.__dict__['class_private_attrib'] "toto" >> s = SubClass() >> s.class_private_attrib "toto" # of course :(
*What I understand:*
Ok, I've re-read the manual, noticed that data descriptors __set__() method was only called when an instance attribute is set (which is obvious from the prototypes of the methods). My solution is plain wrong and I should have guess without ever trying. duh :(
Now please have mercy, you Noble Pythoneers : what's the trick to prevent client code to accidentally mess with the class's dict ? (most client code - apart from subclass definitions - shouldn't even bother about the existence of this attribute, it's there for the library internal usage)
NB : in the real code I'm also messing with the AbstractBaseClass's meta_class for other stuff (so it's not a problem if the solution involves metaclasses), but I've tested with the simplified example above, which exhibits the same problem.
TIA
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')])"
--
http://mail.python.org/mailman/listinfo/python-list