How to restrict settable attributes for an object?

Alex Moffat ajm_NO_REPLY_ at zanthan.com
Wed Oct 9 04:10:52 CEST 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