什么是测试输入是格式良好的数字的最pythonic方式

时间:2008-12-16 14:15:11

标签: python idioms

我有一个函数,它需要实数(整数或浮点数)作为输入,我在尝试对它进行数学运算之前验证这个输入。

我的第一直觉是在try-except块中将输入转换为浮点数。

try:
   myinput = float(input)
except:
   raise ValueError("input is not a well-formed number")

我也可以打电话给isinstance(mydata, (float, int, long) )但是“所有这些可能是数字”的列表对我来说似乎有点不合适。

最狡猾的方式是什么?我忽略了另一种选择吗?

4 个答案:

答案 0 :(得分:12)

How much input validation should I be doing on my python functions/methods?引用自己:

  

对于sum,factorial等计算,pythons内置类型检查会很好。计算将结束upp为类型调用add,mul等,如果它们中断,它们将抛出正确的异常。通过强制执行您自己的检查,您可能会使其他工作输入无效。

因此,最好的选择是将类型检查留给Python。如果计算失败,Python的类型检查会给出异常,所以如果你自己做,你只需要复制代码,这意味着代表你做更多工作。

答案 1 :(得分:5)

在Python 2.6和3.0中,数字抽象数据类型的类型层次结构为added,因此您可以执行以下检查:

>>> import numbers
>>> isValid = isinstance(myinput , numbers.Real)

numbers.Real将匹配整数或浮点类型,但不匹配非数字类型或复数(使用numbers.Complex)。它也会匹配有理数,但可能你也希望包含这些数字。即:

>>> [isinstance(x, numbers.Real) for x in [4, 4.5, "some string", 3+2j]]
[True, True, False, False]

不幸的是,这一切都在Python> = 2.6中,因此如果您正在为2.5或更早版本开发,那么它将无用。

答案 2 :(得分:2)

也许您可以使用assertisinstance语句的组合。 类似下面的内容是我认为更加pythonic的方式,因为当您的输入不符合您的要求时抛出异常。不幸的是,我没有看到任何有效数字比你更好的定义。也许有人会有更好的想法。

number = (float, int, long)
assert isinstance(mydata, (float, int, long))

答案 3 :(得分:1)

我不明白这个问题。

有两种不同语义的东西被作为“替代品”而被抛弃。

类型转换是一回事。它适用于任何支持__float__的对象,它可以是各种各样的对象,其中很少有实际数字。

try:
   myinput = float(input)
except:
   raise ValueError("input is not a well-formed number")
# at this point, input may not be numeric at all
# it may, however, have produced a numeric value

类型测试是另一回事。这仅适用于作为特定类集的正确实例的对象。

isinstance(input, (float, int, long) )
# at this point, input is one of a known list of numeric types

以下是响应float的示例类,但仍不是数字。

class MyStrangeThing( object ):
    def __init__( self, aString ):
        # Some fancy parsing 
    def __float__( self ):
        # extract some numeric value from my thing

“实数(整数或浮点数)”这个问题通常是无关紧要的。许多东西都是“数字”,可以在数字操作中使用,但不是整数或浮点数。例如,您可能已下载或创建了有理数字包。

输入过高是没有意义的,除非您的算法不适用于某些类型。这些很少见,但有些计算需要整数,特别是它们可以进行整数除法和余数运算。对于那些,您可能想断言您的值是整数。