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
-- http://mail.python.org/mailman/listinfo/python-list