check if object is number
Steven Bethard
steven.bethard at gmail.com
Fri Feb 11 17:41:43 EST 2005
George Sakkis wrote:
>>George Sakkis wrote:
>>
>>>"Steven Bethard" <steven.bethard at gmail.com> wrote in message
>>>news:gcidnb9g_ojxnpDfRVn-tA at comcast.com...
>>>
>>>>Is there a good way to determine if an object is a numeric type?
>>>
>>>In your example, what does your application consider to be numeric?
>>
>>Well, here's the basic code:
>>
>>def f(max=None):
>> ...
>> while max is None or n <= max:
>> ...
>> # complicated incrementing of n
>>
>>So for 'max', technically all I need is <= support. However, the code
>>also depends on the fact that after incrementing 'n' enough, it will
>>eventually exceed 'max'. Currently, ints, longs, floats, and Decimals
>>will all meet this behavior. But I'd rather not specify only those 4
>>(e.g. with a typecheck), since someone could relatively easily create
>>their own new numeric type with the same behavior. Do you know a better
>>way to test for this kind of behavior?
>
> The problem is more conceptional rather than technical.
Yup.
> So what you're saying is that 3 <= "3.0" should not be allowed, but
> 3 <= SomeUserDefinedNumericClass(3) is ok, although your program knows
> nothing a priori about SomeUserDefinedNumericClass. The idea suggested
> before, try if "x+1" fails or not does not get you far; any class that
> overrides __add__ may fool this test:
>
> class Dummy:
> def __add__(self,other):
> return 0
Right but by the same logic, we can fool protocols that are builtin to
Python:
py> class C(object):
... def __iter__(self):
... return 0
...
py> for x in C():
... print x
...
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: iter() returned non-iterator of type 'int'
I'm not trying to catch the case where someone is deliberately violating
the protocol. Only the case where they've provided an object that
doesn't conform to the protcol.
Clearly, complex objects don't conform to the protocol I want -- they
don't support comparisons to ints. This is easy to check:
try:
x <= 1
except TypeError:
raise TypeError('%s does not support comparisons to ints' %
type(x).__name__)
Now str objects also don't conform my protocol -- they aren't comparable
to integers in any meaningful sense. Ideally, I should be able to use
the same code as above for str objects (and get a TypeError like "str
objects cannot be compared with int objects"), but unfortunately, the
Python wart of cross-type default comparisons gets in the way. I look
forward to the day when Python 3.0 removes such comparisons. =)
Steve
More information about the Python-list
mailing list