I was thinking about what, in my opinion, is a cleaner solution to implement a pure read-only attribute if that's all you want. This is the solution solution tangentstorm gave, but it generally does not need the __getattr__ method.
class Foo(object): def __init__(self): self.readonly = set() def set_readonly(self, attr, value): setattr(self, attr, value) self.readonly.add(attr) def __setattr__(self, attr, value): if hasattr(self, "readonly") and attr in self.readonly: raise AttributeError("Read only attribute: %s" % (attr,)) object.__setattr__(self, attr, value)
It works as follows:
>>> f = Foo() >>> fx = 5 >>> f.set_readonly("y", 9) >>> fx, fy (5, 9) >>> fx = 7 >>> fy = 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "ro.py", line 13, in __setattr__ raise AttributeError("Read only attribute: %s" % (name,)) AttributeError: Read only attribute: y
To make the read and write attribute read-only easier:
def unset_readonly(self, attr): self.readonly.remove(attr)
In my first attempt to write this idea, I used self.__readonly instead of self.readonly , but this leads to a problem with the actual setting of the __readonly attribute, since I will need to un-munge "private" to check for ( hasattr(self, "_Foo__readonly") ) and this is discouraging.