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