How to restrict settable attributes for an object?
Alex Moffat
ajm_NO_REPLY_ at zanthan.com
Tue Oct 8 22:10:52 EDT 2002
What I want to do is restrict the attributes that can be set on an
object. I want to do this for "data objects" so that I can catch typing
errors in my program and more easily manage sql interfacing. My current
"solution" is pasted below. Is there a better technique that I should
use. I'm new to python so I'd like to try and follow the established
idioms and patterns where they exist.
In a file DataObject.py I have
def defAllowedAttributes(clazz, attrList):
"""Define the attributes that are allowed for objects of a class.
This consists of those passed in as attrList as any that are
defined for superclasses of clazz."""
allowedAttrs = {}
for a in attrList:
allowedAttrs[a] = None
for c in clazz.__bases__:
allowedAttrsName = "_%s__allowedAttrs" % c.__name__
for a in getattr(c, allowedAttrsName):
allowedAttrs[a] = None
allowedAttrsName = "_%s__allowedAttrs" % clazz.__name__
setattr(clazz, allowedAttrsName, allowedAttrs)
class DataObject:
"""A base class for objects with a restricted set of attributes."""
def _isAllowed(self, a):
allowedAttrsName = "_%s__allowedAttrs" % self.__class__.__name__
if a in getattr(self.__class__, allowedAttrsName):
return 1
else:
return 0
def __setattr__(self, name, value):
"""only set values for allowed attributes"""
if self._isAllowed(name):
self.__dict__[name] = value
else:
raise AttributeError, \
"%s instance allows no attribute '%s'" % \
(self.__class__.__name__, name)
def __getattr__(self, name):
"""if name is an allowed attribute then return None"""
if self._isAllowed(name):
return None
else:
raise AttributeError, \
"%s instance allows no attribute '%s'" % \
(self.__class__.__name__, name)
# Set up DataObject with an initially empty set
defAllowedAttributes(DataObject, [])
In a file called TestDataObject.py
import DataObject
class A(DataObject.DataObject):
pass
DataObject.defAllowedAttributes(A, ("a", "b"))
class B(A):
pass
DataObject.defAllowedAttributes(B, ("c", "d"))
if __name__ == "__main__":
a = A()
a.a = "1"
a.b = "2"
try:
a.c = "3"
except AttributeError, ar:
pass
b = B()
b.a = "1"
b.b = "2"
b.c = "3"
b.d = "4"
try:
a.e = "5"
except AttributeError, ar:
pass
More information about the Python-list
mailing list