On Jun 22, 5:44 am, "Josip" <[EMAIL PROTECTED]> wrote: > I'm trying to limit a value stored by object (either int or float): > > class Limited(object): > def __init__(self, value, min, max): > self.min, self.max = min, max > self.n = value > def set_n(self,value): > if value < self.min: # boundary check > self.n = self.min > if value > self.max: > self.n = self.max > else: > self.n = value > n = property(lambda self : self._value, set_n) > > This works,
I bet you didn't even try this, unless your definition of "works" includes a "RuntimeError: maximum recursion depth exceeded". Here's a a working version: class Limited(object): def __init__(self, value, min, max): self.min, self.max = min, max self.n = value n = property(lambda self : self._value, lambda self,value: self.__dict__.__setitem__('_value', max(self.min, min(value, self.max)))) def __int__(self): return int(self._value) def __float__(self): return float(self._value) a = Limited(11, 0, 9) print float(a) import math print math.sqrt(a) > except I would like the class to behave like built-in types, so > I can use it like this: > > a = Limited(7, 0, 10) > b = math.sin(a) > > So that object itself returns it's value (which is stored in a.n). Is this > possible? For (most) math.* functions it suffices to define __float__, so the above works. For making it behave (almost) like a regular number, you'd have to write many more special methods: http://docs.python.org/ref/numeric-types.html. Here's a possible start: import operator class Limited(object): def __init__(self, value, min, max): self.min, self.max = min, max self.n = value n = property(lambda self : self._value, lambda self,value: self.__dict__.__setitem__('_value', max(self.min, min(value, self.max)))) def __str__(self): return str(self.n) def __repr__(self): return 'Limited(%r, min=%r, max=%r)' % (self.n, self.min, self.max) def __int__(self): return int(self._value) def __float__(self): return float(self._value) def __add__(self, other): return self._apply(operator.add, self, other) def __sub__(self, other): return self._apply(operator.sub, self, other) # a few dozens more methods follow ... def __radd__(self, other): return self._apply(operator.add, other, self) def __rsub__(self, other): return self._apply(operator.sub, other, self) # a few dozens more methods follow ... @classmethod def _apply(cls, op, first, second): minmax = None if isinstance(first, cls): minmax = first.min,first.max first = first._value if isinstance(second, cls): if minmax is None: minmax = second.min,second.max second = second._value return cls(op(first,second), *minmax) a = Limited(11, 0, 9) print a+1 print 1+a print a-1 print 1-a Needless to say, this is almost two orders of magnitude slower than the builtin numbers, so you'd better not use it for any serious number crunching. HTH, George -- http://mail.python.org/mailman/listinfo/python-list