On Jun 23, 1:24 am, "Josip" <[EMAIL PROTECTED]> wrote: > > Why not make it a function? > > > function assignLimited(value, vmin, vmax): > > value = max(vmin, value) > > value = min(vmax, value) > > return value > > > a = assignLimited(7, 0, 10) > > > Seems like it solves your problem relatively cleanly. > > Note: I also removed min/max variables because they would mask the > > built-in min/max functions. > > > -Larry >
> Still, I'm going for object > oriented solution because I want the value and it's limits to be kept > together as I'll have many such values with different limits. In that case, "overriding assignment" makes no sense since if an operation is done on two values that have two different limits, what would happen? Take the first's or second's limits, or interpolate the new limit by some magic function? A much better solution would be for operation to always return plain vanilla int, and we set limits explicitly. > Storing all > the limits in caller namespace is not really an option. You want to store limits in the object too? Try this: (_LimitedInt inherits from int, so operator overloading is unnecessary) ### #!/usr/bin/env python class _LimitedInt(int): class InvalidLimitsError(Exception): pass def __init__(self, value, base = 10): int.__init__(value, base) def setlimits(self, lim): ''' Set the limits and if value is not within limit, raise ValueError The lim argument accepts: - A _LimitedInt instance, from which to copy the limits - A two-tuple, which specifies the limits i.e. (min, max) If lim isn't those or lim[0] > lim[1], raise InvalidLimitsError Accepting _LimitedInt instance is just for convenience ''' if isinstance(lim, _LimitedInt): lim = lim.limits try: self.min, self.max = [int(x) for x in lim] if self.min > self.max: raise ValueError except (ValueError, TypeError): raise self.InvalidLimitsError, ('limit = %s' % str(lim)) if not (self.min < self < self.max): raise ValueError, \ ('val = %s, min = %s, max = %s' % \ (self, self.min, self.max)) def getlimits(self): return (self.min, self.max) limits = property(getlimits, setlimits) def lint(value, limits, base = 10): if base != 10: ret = _LimitedInt(value, base) else: ret = _LimitedInt(value) ret.limits = limits return ret ### END OF REAL CODE ### ### THE REST ARE JUST TESTING CODES ### if __name__ == '__main__': print 'Instantiating lint...' a = lint(50, (0, 200)) # Limit explicitly specified b = lint(150, a) # Copy the limits of a c = lint(a, (0, 1000)) # Value = a, Limit = (0, 1000) d = lint(a, c) # Value = a, Limit = c print print 'Printing the value and the limits...' print a, a.limits print b, b.limits print c, c.limits print d, d.limits print print 'Changing limits' print 'Note: lint is partially immutable,' print ' its limits is mutable,' print ' while its value is immutable' a.limits = (0, 300) b.limits = a print a, a.limits print b, b.limits print print '"Changing" values' a = lint(b, a) print a, a.limits print print 'Operations...' e = lint(a + b - c * d + 100, (-10000, 1000)) f = a + b - c * d ## Operation returns plain integer g = lint(f, (-100000, 100000)) ## Always recast result of operator print e, e.limits, type(e) ## This is an int, not lint print f, type(f) ## BEWARE: f is integer, it has no limits print g, g.limits, type(g) ## INVALIDS # a = lint(100, (1000, 100000)) # a = lint(100, 'ab') # a = lint(100, (10000, 0)) # a = lint(100, 10) # a = lint(100, (10, 1000, 10000))### -- http://mail.python.org/mailman/listinfo/python-list