Getters and Setters

Neil Schemenauer nascheme at ucalgary.ca
Thu Jul 15 01:33:04 EDT 1999


Recently I found myself wishing that Python had automatic getters
and setters like CLOS. For those who are not familiar, CLOS (and
Dylan) create a "getter" and "setter" method for each attribute
of a class. This saves the programmer from writing "getX" and
"setX" for every attribute when no special action is needed.
Later, an explict method can be created if needed.

An implementation of this idea is attached.  With this
implementation, these automatic methods seem to be about 8 times
slower than explicit methods.  Maybe Tim and friends can do
something about that.  I would appreciate any comments.

On a related note, has anyone considered adding hygenic macros to
Python?  Due to the high cost of function calls in Python they
would probably be a useful (and for other things too).  I have
the feeling that hygenic macros are much easier to do in a
language like Lisp.  Maybe Dylan can give us some ideas.


    Neil


======================================================================
#
# A mixin class to automagicly create getter/setter methods for
# class attributes. By default the method names are get* and
# set*. Modify as desired. Using the automatic methods seems to
# be about 8 times slower than explicit methods.
#
# Neil Schemenauer, July 1999
#

class _Getter:
    def __init__(self, value=None):
        self.value = value

    def __call__(self):
        return self.value

class _Setter:
    def __init__(self, klass=None, name=None):
        self.klass = klass
        self.name = name

    def __call__(self, value):
        self.klass.__dict__[self.name] = value
        del self.klass

class GetterSetter:
    def __getattr__(self, name, getter=_Getter(), setter=_Setter()):
        try:
            if name[:3] == 'get':
                getter.value = self.__dict__[name[3:]]
                return getter
            elif name[:3] == 'set':
                setter.klass = self
                setter.name = name[3:]
                return setter
        except KeyError:
            pass
        raise AttributeError


def test():
    import time
    class A(GetterSetter):
        def __init__(self):
            self.X = self.Y = 1
        def getY(self):
            return self.Y
        def setY(self, v):
            self.Y = v
    a = A()
    t = time.time()
    n = 10000
    print 'Comparing', n, 'iterations'
    for x in range(n):
        a.getX()
        a.setX(1)
    print 'GetterSetter', time.time()-t
    t = time.time()
    for x in range(n):
        a.getY()
        a.setY(1)
    print 'explicit function', time.time()-t


if __name__ == '__main__': test()




More information about the Python-list mailing list