subclass of integers
Ian Clark
iclark at mail.ewu.edu
Fri Sep 14 16:46:35 EDT 2007
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.
>
> It's simple enough to construct a subclass of integers that behave in
> this way:
>
> class Nint(int):
> def __add__(self,other):
> if (other != None):
> return self+other
> else:
> return None
> def __radd__(self,other):
> if (other != None):
> return other+self
> else:
> return None
> #...and so forth
>
> However I have not been able to figure out how to make it so that
> None, as well as an integer, could be an element of my class. My
> preliminary impression is that I have to override int.__new__; but I
> am uncertain how to do that and have been unable to find anything on
> the web explaining that. Indeed I haven't been able to find much
> about __new__ at all. Overriding this method of built-in classes
> seems to be quite unusual.
>
> 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...
-----8<--------------------------------------------------
class NoneInt(object):
def __init__(self, value):
self.value = value
def __add__(self, other):
if isinstance(other, NoneInt):
if None in (self.value, other.value):
return NoneInt(None)
return NoneInt(self.value + other.value)
elif isinstance(other, int):
if self.value is None:
return NoneInt(None)
return NoneInt(self.value + other)
else:
raise TypeError(
"unsupported operand type(s) for +: 'NoneInt'"
"and '%s'" % str(other.__class__.__name__)
)
__radd__ = __add__
def __str__(self):
return 'NoneInt(%s)' % str(self.value)
def main():
print '42? ', NoneInt(40) + NoneInt(2)
print '41? ', NoneInt(40) + 1
print '40? ', 25 + NoneInt(15)
print 'None? ', NoneInt(None)
print 'None? ', NoneInt(None) + 1
print 'None? ', 1 + NoneInt(None)
print 'Error? ', NoneInt(0) + 'spam'
if __name__ == '__main__':
main()
-----8<--------------------------------------------------
Ian
More information about the Python-list
mailing list