accessor/mutator functions

Michael Spencer mahs at telcopartners.com
Fri Feb 25 13:03:20 EST 2005


mirandacascade at yahoo.com wrote:
> If the class had two attributes--x and y--would the code look like
> something lik this:
> 
>  class C(object):
>         def __init__(self):
>             self.__x = 0
>             self.__y = 0
>         def getx(self):
>             return self.__x
>         def setx(self, x):
>             if x < 0: x = 0
>             self.__x = x
>         def gety(self):
>             return self.__y
>         def sety(self, y):
>             if y < 0: y = 0
>             self.__y = y
>         x = property(getx, setx)
>         y = property(gety, sety)

It could do - that works.  One feature of this solution is that it leaves the 
accessor/mutator functions in the namespace.  That may be a good or a bad thing. 
  If bad, you could simply delete them after the property call (which is 
probably better written as close as possible to the functions)

i.e., class C(object):
    def __init__(self):
        self.__x = 0
        self.__y = 0
    def getx(self):
        return self.__x
    def setx(self, x):
        if x < 0: x = 0
        self.__x = x
    x = property(getx, setx)
    del getx, setx
    def gety(self):
        return self.__y
    def sety(self, y):
        if y < 0: y = 0
        self.__y = y
    y = property(gety, sety)
    del gety, sety

There are also recipes in the cookbook for defining property "suites" more elegantly

Note, that it is also easy to "roll your own" descriptor, which may be 
worthwhile if you have a lot of similar properties, for example (not tested 
beyond what you see):

from weakref import WeakKeyDictionary

class Property(object):
     def __init__(self, adapter):
         """adapter is a single argument function that will be
             applied to the value before setting it"""
         self.objdict = WeakKeyDictionary()
         self.adapter = adapter
     def __get__(self, obj, cls):
         if isinstance(obj, cls):
             return self.objdict[obj]
         else:
             return self
     def __set__(self, obj, value):
         self.objdict[obj] = self.adapter(value)

class C(object):
     x = Property(lambda val: max(val, 0))
     y = Property(lambda val: val%2)
     z = Property(abs)

  >>> c= C()
  >>> c.x = -3
  >>> c.x
0
  >>> c.y = -3
  >>> c.y
1
  >>> c.z = -3
  >>> c.z
3
  >>>


Michael




More information about the Python-list mailing list