check if object is number

Michael Spencer mahs at telcopartners.com
Sat Feb 12 18:03:42 EST 2005


Steven Bethard wrote:
> Peter Hansen wrote:
> 
>> Of course, most of the other definitions of "is a number" that
>> have been posted may likewise fail (defined as not doing what the
>> OP would have wanted, in this case) with a numarray arange.
>> Or maybe not.  (Pretty much all of them will call an arange a
>> number... would the OP's function work properly with that?)
> 
> 
> No, but it will fail properly since my code basically looks like:
> 
> def f(max=None):
>     ...
>     while max is None or n <= max:
>         ...
>         # complicated incrementing of n
> 
> So if max is an array, though all of the proposed isnumber checks will 
> call it a number, my code will (rightly) fail when the array (n <= max) 
> gets __nonzero__ called in the while condition.  I guess I'd prefer it 
> to fail in the isnumber check, but overall, I'm more concerned that 
> _some_ error is produced, not necessarily which one.  (I'm also not 
> thrilled that bool(array) raises a RuntimeError instead of a TypeError...)
> 
> Steve
Steve,

How about explicitly calling an adapter in your function, e.g.?

 > def f(max=None):
 >     max = number(max)
 >     while max is None or n <= max:
 >         ...
 >         # complicated incrementing of n

then you can define number to document the required behavior and return more 
useful exceptions if the object fails.  At the same time, anyone who wants to 
use a custom number class with your function has a ready-made unittest.

  >>> def number(obj):
  ...     """Adapts obj to be numeric, or fails helpfully"""
  ...     if isinstance(obj, (int, float, long, )): # these types conform
  ...        return obj
  ...     elif isinstance(obj, basestring): # these types have a known adaptation
  ...        return int(obj)
  ...     else: # check the object exhibits the required behavior
  ...        try:
  ...            assert obj+1 >= 1
  ...        except Exception, err:
  ...            raise TypeError, "obj does not support addition and comparisons 
with numbers (%s)" % err
  ...        return obj
  ...
  >>> class MyNumber(object):
  ...     def __init__(self, data):
  ...        self.data = data
  ...     def __add__(self, other):
  ...        return MyNumber(self.data + other)
  ...     def __cmp__(self, other):
  ...        return self.data.__cmp__(other)
  ...
  >>> a = MyNumber(42)
  >>> a is number(a)
True
  >>>
  >>> number(1+2j)
Traceback (most recent call last):
   File "<input>", line 1, in ?
   File "<input>", line 11, in number
TypeError: obj does not support addition and comparisons with numbers (cannot 
compare complex numbers using <, <=, >, >=)
  >>> number(array.array("i",[1]))
Traceback (most recent call last):
   File "<input>", line 1, in ?
   File "<input>", line 11, in number
TypeError: obj does not support addition and comparisons with numbers (can only 
append array (not "int") to array)
  >>>

Cheers
Michael




More information about the Python-list mailing list