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