subclass of integers
Ian Clark
iclark at mail.ewu.edu
Fri Sep 14 18:38:11 EDT 2007
Ian Clark wrote:
> Mark Morss wrote:
>> I would like to construct a class that includes both the integers and
>> None. I desire that if x and y are elements of this class, and both
>> are integers, then arithmetic operations between them, such as x+y,
>> return the same result as integer addition. However if either x or y
>> is None, these operations return None.
>>
>> (snip)
>>
>> I would very much appreciate anyone's help.
>
> My thought would be rather than trying to cram None into a subclass of
> int, to use delegation instead...
>
> (snip)
>
> Ian
A more robust implementation that accounts for ints/longs as well as
implementing more operations...
-----8<--------------------------------------------------
import operator
class NoneInt(object):
_LEFT = 1
_RIGHT = 2
def __init__(self, value):
self.value = value
def _get_arguments(self, other, direction=_LEFT):
""" Given a direction (left or right), returns the left hand
side and right hand side values. """
if direction == self._LEFT:
lhs = self.value
if isinstance(other, (int, long, type(None))):
rhs = other
else:
rhs = other.value
elif direction == self._RIGHT:
rhs = self.value
if isinstance(other, (int, long, type(None))):
lhs = other
else:
lhs = other.value
else:
raise ValueError('direction must be either _LEFT or _RIGHT')
return (lhs, rhs)
def _operation(op, direction):
""" Given a direction and an operation will return a function
that calls the operation with the arguments in the correct
order. """
def func(self, other):
if not isinstance(other, (int, long, NoneInt, type(None))):
fmt = "unsupported operand type(s) for %s: 'NoneInt'
and '%s'"
args = (op.__name__, other.__class__.__name__)
raise TypeError(fmt % args)
lhs, rhs = self._get_arguments(other, direction)
if None in (lhs, rhs):
return NoneInt(None)
return NoneInt(op(lhs, rhs))
return func
__add__ = _operation(operator.add, _LEFT)
__radd__ = _operation(operator.add, _RIGHT)
__sub__ = _operation(operator.sub, _LEFT)
__rsub__ = _operation(operator.sub, _RIGHT)
__div__ = _operation(operator.div, _LEFT)
__rdiv__ = _operation(operator.div, _RIGHT)
__mul__ = _operation(operator.mul, _LEFT)
__rmul__ = _operation(operator.mul, _RIGHT)
# ... etc
def __eq__(self, other):
lhs, rhs = self._get_arguments(other)
return lhs == rhs
def __nonzero__(self):
return bool(self.value)
def __str__(self):
return 'NoneInt(%s)' % str(self.value)
__repr__ = __str__
-----8<--------------------------------------------------
Ian
More information about the Python-list
mailing list