subclass of integers

Ian Clark iclark at mail.ewu.edu
Fri Sep 14 22:46:35 CEST 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