Velocity Reviews > Now that rexec is gone...

# Now that rexec is gone...

Jeff Epler
Guest
Posts: n/a

 09-29-2003
First, whatever test you use, you should probably encapsulate it in a
function, so that if you need to update the definition you can do it at

def isnumeric(x):
return isinstance(x, (int, long, float))

You could have a registry of numeric types:

_numeric_types = ()
def register_numeric_type(t):
global _numeric_types
if t in _numeric_types: return
_numeric_types += (t,)

for value in (0, 0., 0l, 0j):
register_numeric_type(type(value))

def isnumeric(x):
return isinstance(x, _numeric_types)

Now, if someone wants to write a vector type, it merely needs to be
registered.

You could test that common numeric operations work:
def isnumeric(x):
try:
if x*1 == x and x+0 == x:
return 1
except TypeError:
pass
return 0

You could just run your code and let the eventual TypeError speak for
def f(x):
if not isnumeric(x): raise TypeError, "can't f() a %s" % type(x)
return x*x
just write
def f2(x):
return x*x
The difference in the quality of the error message is not large:
>>> f("")

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in f
TypeError: can't f() a <type 'str'>
>>> f2("")

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in f2
TypeError: unsupported operand type(s) for *: 'str' and 'str'

Jeff

Jean-S?bastien Bolduc
Guest
Posts: n/a

 09-30-2003
> > How do I check if a value is a number in Python?
> >
> > One way is (x == type(1)) and (x == type(1.2)) and (x ==
> > type(2387482734274)) and ...

>
> Why do you want to do so? Maybe, it is better in your
> case to just run the piece of code using the number, and
> if it fails, it fails. However, if you must, you need to
> do type(x) is type(1) and ... etc., or isinstance(x, int)
> and isinstance(x, float), etc.

I used to use the latter approach suggested by Gerrit, but I recently
found on the web an alternative, elegant approach that might work
(sorry, I don't recall where I found it!):

hasattr(x, '__int__')

If the "__int__" method is defined for "x", it is a number. This will
work for integer, long, float and complex types, as well as for custom
classes that emulate numeric types.

Regards,
JSeb

Erik Max Francis
Guest
Posts: n/a

 09-30-2003
Jean-S?bastien Bolduc wrote:

> I used to use the latter approach suggested by Gerrit, but I recently
> found on the web an alternative, elegant approach that might work
> (sorry, I don't recall where I found it!):
>
> hasattr(x, '__int__')
>
> If the "__int__" method is defined for "x", it is a number. This will
> work for integer, long, float and complex types, as well as for custom
> classes that emulate numeric types.

This is an insidiously bad idea, in my opinion. All having an __int__
method means is there is some _conversion_ from an instance to an int
type. It does not at all mean the custom instance spends most of its
life behaving as an integer.

--
Erik Max Francis && http://www.velocityreviews.com/forums/(E-Mail Removed) && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ We grow in time to trust the future for our answers.
\__/ Ruth Benedict

Aahz
Guest
Posts: n/a

 10-02-2003
In article <(E-Mail Removed)>,
Erik Max Francis <(E-Mail Removed)> wrote:
>Jean-S?bastien Bolduc wrote:
>>
>> If the "__int__" method is defined for "x", it is a number. This will
>> work for integer, long, float and complex types, as well as for custom
>> classes that emulate numeric types.

>
>This is an insidiously bad idea, in my opinion. All having an __int__
>method means is there is some _conversion_ from an instance to an int
>type. It does not at all mean the custom instance spends most of its
>life behaving as an integer.

Yup. There's been some talk of adding an __index___() method or
something to deal with that.
--
Aahz ((E-Mail Removed)) <*> http://www.pythoncraft.com/

"It is easier to optimize correct code than to correct optimized code."
--Bill Harlan