Welcome, guest | Sign In | My Account | Store | Cart
import sys

def attribute(attrname, permit='rwd', fget=None, fset=None, fdel=None, doc=''):
    """returns a property associated with 'attrname'.
    
       By default, a simple property with get, set, and delete methods
       will be created. Optionally, specific get/set/del methods may be
       supplied. You can also choose to omit the creation of one or more
       of the default get/set/del methods via the 'permit' flag:
           'r': readable, 'w':writable, 'd':deletable
       So, if you want a property that is readable and deletable, but not
       writable, use "permit='rd'".
    """
    if _isprivate(attrname):
        attrname = _mangle(_get_classname(), attrname)
    if 'r' in permit and fget is None:
        fget = lambda self: getattr(self, attrname)
    if 'w' in permit and fset is None:
        fset = lambda self, value: setattr(self, attrname, value)
    if 'd' in permit and fdel is None:
        fdel = lambda self: delattr(self, attrname)
    return property(fget, fset, fdel, doc)

def _isprivate(attrname):
    return attrname.startswith("__") and not attrname.endswith("__")

def _mangle(classname, attrname):
    '''mangles name according to python name-mangling 
       conventions for private variables'''
    return "_%s%s" % (classname, attrname)

def _get_classname():
    "returns the calling class' name"
    frame = sys._getframe(2)
    classname = frame.f_code.co_name
    return classname

# example
if __name__ == "__main__":
    class C(object):
        a = attribute('_a', fget=lambda self: self._a*2)
        def __init__(self):
            self._a = "A"

    c = C()
    print c.a  # uses a.fget, user supplied
    c.a = "AA" # uses a.fset, provided by default
    print c.a

History