文章来自《Python cookbook》.


-- 0.706 [2004-09-19 16:03:36]

Testing Whether a String Represents an Integer 检测一个字符串是否表达一个整数

Credit: Robin Parmar

问题 Problem

ou 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).


解决 Solution

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


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

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


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

讨论 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:

让一个Python 源文件既能作为一个脚本运行,又能通过import使用,总是一个好主意. 当作为一个脚本运行时,某种单元测试或演示代码就运行了.在这个实例中,例如,对包含这个配方中函数的小模块,我们可以用下面的代码作为结束:

   1 if _ _name_ _ == '_ _main_ _':
   2     print isInt('23')
   3     print isInt('sd')
   4     print isInt('233835859285')
   5     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.

把这个模块作为一个脚本运行,可以确认: 23表示一个整数,sd不是,并且233835859285也不是(因为它太大,大于sys.maxint的整数是不能被定义的.译者:在python2.3中,int('233835859285')将返回一个长整数,而不是抛出异常.因此本配方中的模块会确认233835859285是整数).可是,就象第四个或最后一个打印语句所表明的,233835859285确实全由数字组成.

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.

异常提供了一个完成某些简单测试的便利方法.例如,如果你想知道是否一个字符串的内容表达一个整数,为什么不试图把它转化(为整数)?这就是isInt做的,当字符串不能转化为整数时,抛出的异常被try/except机制捕获,在异常处理中,把异常转变成一个无害的return 0 . 后面的else子句只有当没有异常发生时才执行,本例中,我们用它在字符串的内容确实表达一个整数时return 1.

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.

你能够对整数外的类型写出类似的测试.实际上,以try/except方式测试,对于那些字符串表示更复杂的类型甚至更有用处,比如浮点数.更一般的,异常能提供简单、直接的方法来完成许多用其它方法相当费力的测试.不要被"exception"这个词以及其它语言中尊崇的好风格误导。在Python中,异常在很多并非异常的情况下也是很有用的。依赖于异常以及try/except 来完成确认工作是高度Pythonic、实际而且有用的习惯用法。它甚至有自己的名字,"It's Easier to Ask Forgiveness Than Permission",缩写为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).

这种类型测试与检查一个字符串是否只包含数字的纯语法测试有很大不同.在相对稀罕的情况下,你只在意纯语法表达而完全不关心实际语义,isAllDigits 会帮助你.这种风格称作"Look Before You Leap" (LBYL),尽管有许多缺陷,在许多稀罕的情况下,它确实正是你需要的。在Python2.0及以后,字符串对象的isdigit方法完全完成与本配方中isAllDigits函数同样的测试,但更快速。独特的是.isdigit( )返回0,而IsAllDigits() 返回 1.当然这容易补偿,总之,通过在代码中为not astring插入一个合适的检查就行(字符串,象其它序列一样,只有为空时才是一个false值)。

参考 See Also

Documentation for the built-in function int in the Library Reference.

PyCkBk-3-13 (last edited 2009-12-25 07:11:00 by localhost)