I l@ve RuBoard

3.13 Testing Whether a String Represents an Integer

Credit: Robin Parmar

3.13.1 Problem

You want to know whether the contents of a string represent an integer (which is not quite the same thing as checking whether the string contains only digits).

3.13.2 Solution

try/except is almost invariably the best approach to such validation problems:

```def isInt(astring):
""" Is the given string an integer? """
try: int(astring)
except ValueError: return 0
else: return 1```

Testing if a string contains only digits is a different problem:

```def isAllDigits(astring):
""" Is the given string composed entirely of digits? """
# In Python 2.0 and later, "astring.isdigit(  ) or not astring" is faster
import string
acceptable_characters = string.digits
for acharacter in astring:
if acharacter not in acceptable_characters:
return 0
return 1```

3.13.3 Discussion

It's always a good idea to make a Python source file runnable as a script, as well as usable via import. When run as a script, some kind of unit test or demo code executes. In this case, for example, we can finish up the little module containing this recipe's functions with:

```if _ _name_ _ == '_ _main_ _':
print isInt('23')
print isInt('sd')
print isInt('233835859285')
print isAllDigits('233835859285')```

Running the module as a script will now confirm that 23 represents an integer, sd does not, and neither does 233835859285 (because it's too large梚t would need an integer greater than sys.maxint, which is impossible by definition). However, as the fourth and last print statement shows, even the latter string is indeed made up entirely of digits.

Exceptions provide a handy way of performing simple tests. For example, if you want to know whether the contents of a string represent an integer, why not just try to convert it? That's what isInt does. The try/except mechanism catches the exception raised when the string cannot be converted to an integer and, in the exception handler thus established, turns the exception into a harmless return 0. The else clause runs only when no exception is raised in the try clause, and in this case, we use it to perform a return 1 when the string is okay.

You can write similar tests for types other than integer. Indeed, tests in the try/except style are even more useful for types with string representation that can be more complicated, such as floats. More generally, exceptions can provide a simple, direct way of performing many tests that could otherwise be quite laborious. Don't be misled by the word "exception" or by what is considered good style in other programming languages. In Python, exceptions are useful for many nonexceptional cases, too. Relying on exceptions and try/except for validation tasks is a highly Pythonic, pragmatic, and useful idiom. It even has its own name, "It's Easier to Ask Forgiveness Than Permission", and acronym, EAFTP.

This type-like test is quite different from the pure-syntax testing of whether a string contains only digits. isAllDigits will help you there, in the relatively rare cases in which you care only about such purely syntactical aspects and not about the actual semantics at all. This style of validation is also known as "Look Before You Leap" (LBYL), and, while it has many pitfalls, in some rare cases it is indeed exactly what you need. In Python 2.0 and later, the isdigit method of string objects performs substantially the same test as the isAllDigits function shown in this recipe, but faster. One peculiarity is that ''.isdigit( ) is 0, while IsAllDigits('') is 1. It is of course easy to compensate for this, either way, by inserting a suitable check for not astring in the code (strings, like other sequences, are false if and only if they're empty).