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�it 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).
3.13.4 See Also
Documentation for the built-in function int in the
Library Reference.
|