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
-- http://mail.python.org/mailman/listinfo/python-list