subclass of integers

Michael Spencer mahs at telcopartners.com
Fri Sep 14 14:14:23 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.
> 
Do you really need to define one class that can represent None and the integers? 
   integers already behave as you want, except that they cannot do binary 
operations with None.  So why not simply define a NoneInt object?

  >>> class NoneInt(object):
  ...     def _all_binops(self, other):
  ...         if isinstance(other, (int, NoneInt)):
  ...             return NoneInt()
  ...         else:
  ...             raise TypeError()
  ...     __add__ = __radd__ = _all_binops
  ...     # ...add comparison, unary methods to taste
  ...     def __repr__(self):
  ...         return "NoneInt()"
  ...
  >>> 3+NoneInt()
  NoneInt()
  >>> NoneInt()+2
  NoneInt()
  >>> "s"+NoneInt()
  Traceback (most recent call last):
    File "<input>", line 1, in <module>
    File "<input>", line 6, in _all_binops
  TypeError
  >>>

Getting back to your question, you can indeed override int.__new__ to return 
something other than a raw int.  This explains how and why:
http://www.python.org/download/releases/2.2.3/descrintro/
But unless there's more to your requirement than you set out above, it's 
probably not worth the trouble.

HTH, Michael






More information about the Python-list mailing list