File: access.py

"""
Private and Public declarations for instances of classes,
via 2.6+ class decorators.  Controls access to attributes
stored on an instance, or inherited by it from its classes.

Private() declares attribute names that cannot be fetched
or assigned outside the subject class, and Public() declares
all the names that can.  See private.py for implementation
notes and a usage example; this generalizes the code to
allow for a Public inverse.
"""

traceMe = False
def trace(*args):
    if traceMe: print '[' + ' '.join(map(str, args)) + ']'

def accessControl(failIf):
    def onDecorator(aClass):
        class onInstance:
            def __init__(self, *args, **kargs):
                self.__wrapped = aClass(*args, **kargs)
            def __getattr__(self, attr):
                trace('get:', attr)
                if failIf(attr):
                    raise TypeError, 'private attribute fetch: ' + attr
                else:
                    return getattr(self.__wrapped, attr)
            def __setattr__(self, attr, value):
                trace('set:', attr, value)
                if attr == '_onInstance__wrapped':
                    self.__dict__[attr] = value
                elif failIf(attr):
                    raise TypeError, 'private attribute change: ' + attr
                else:
                    setattr(self.__wrapped, attr, value)
        return onInstance
    return onDecorator

def Private(*attributes):
    return accessControl(failIf=(lambda attr: attr in attributes))

def Public(*attributes):
    return accessControl(failIf=(lambda attr: attr not in attributes))



[Home page] Books Code Blog Python Author Train Find ©M.Lutz