isNumber? check

Bengt Richter bokr at oz.net
Mon Sep 29 20:48:56 EDT 2003


On Mon, 29 Sep 2003 16:47:07 -0400, Rob Hunter <rob at cs.brown.edu> wrote:

>
>On Monday, September 29, 2003, at 04:41 PM, Gerrit Holl wrote:
>
>> Rob Hunter wrote:
>>> On Monday, September 29, 2003, at 10:20 AM, Gerrit Holl wrote:
>>>> Rob Hunter wrote:
>>>>> How do I check if a value is a number in Python?
>>>>>
>>>>>
>>>>>
>>>>
>>>> Why do you want to do so?
>>>
>>>
>>> I am writing an interpreter, and my parser has to decide if an
>>> expression is a number or not.
>>
>> So you actually have a string...
>>
>> Maybe you could do something like this:
>>
>> if expr.strip("0123456789.e") == "": print "May be a number!"
>> if expr.strip("0123456789") == "": print "Surely a number!"
>>
>> Gerrit.
>>
>
>I don't like that solution for this particular project because, as you 
>say yourself, if it says yes to the second question, it only *may* be a 
>number.  I want to know for sure.  I think the type or instance checks 
>as the other posters mentioned are going to be fine for me.
I guess you'll have to eval the string before type checking the result then,
unless you are already tokenizing your input using the python tokenizer.
Then you could check what it thinks, e.g., (of course you don't need all
this fluff to do a check on a token t -- you don't have to retrieve the
token name from token either, to check whether it is a number, e.g.,

 >>> import tokenize, token, StringIO
 >>> s = '123'
 >>> t = tokenize.generate_tokens(StringIO.StringIO(s).readline).next()
 >>> t
 (2, '123', (1, 0), (1, 3), '123')
 >>> t[0]==tokenize.NUMBER
 True

So you might want to look into letting python's tokenizer module do that part
for your language, unless you have something pretty different...
(obviously StringIO.StringIO(s).readline would be file('yoursource').readline
and you would make more than one call to next ;-)


====< isnumtok.py >===========================================
# isnumtok.py -- check whether string is numeric token as tokenizer sees it 
import tokenize, token, StringIO
def isnumtok(s):
    tnt = [(token.tok_name[t[0]],t[1]) for t in
             tokenize.generate_tokens(StringIO.StringIO(s).readline)]
    toknam, tokval = tnt.pop(0)
    if toknam=='NUMBER' and tokval==s:
        return True, ('"%s" is a number' % tokval)
    elif toknam=='NUMBER':
        return False, ('"%s" leads with the number "%s" but as a whole is not a number'%
                            (s,tokval))
    else:
        return False, ('"%s" is not a number, but leads with the %s "%s"'%
                            (s, toknam, tokval))
    
if __name__ == '__main__':
    import sys
    for arg in sys.argv[1:]: print '%6s: %s' % isnumtok(arg)
==============================================================
Some tests:

[17:53] C:\pywk\clp>isnumtok.py  123 12.34 12.34e10 12.34e-10 123.456**-10 2.3j 2.3x xx +1
  True: "123" is a number
  True: "12.34" is a number
  True: "12.34e10" is a number
  True: "12.34e-10" is a number
 False: "123.456**-10" leads with the number "123.456" but as a whole is not a number
  True: "2.3j" is a number
 False: "2.3x" leads with the number "2.3" but as a whole is not a number
 False: "xx" is not a number, but leads with the NAME "xx"
 False: "+1" is not a number, but leads with the OP "+"

It's not really too clear what the context for your checking is. Perhaps
you are analyzing expressions and bindings and trying to infer types for
bindings of symbols that are NAME token in the source, but bound to objects
that are NUMBER token literals in the source, etc.?

Regards,
Bengt Richter




More information about the Python-list mailing list