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