2

我有一个期望实数(整数或浮点数)作为其输入的函数,并且我试图在对其进行数学运算之前验证此输入。

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

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

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

最pythonic的方式是什么?还有另一个我忽略的选择吗?

4

4 回答 4

12

引用我自己应该对我的 python 函数/方法进行多少输入验证?

对于总和、阶乘等计算,python 内置的类型检查就可以了。计算最终会为这些类型调用 add、mul 等,如果它们中断,它们无论如何都会抛出正确的异常。通过执行您自己的检查,您可能会使其他工作输入无效。

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

于 2008-12-16T14:26:45.180 回答
5

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

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

numbers.Real 将匹配整数或浮点类型,但不匹配非数字类型或复数(为此使用 numbers.Complex)。它也会匹配有理数,但大概你也想包括那些。IE:

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

不幸的是,这一切都在 Python >=2.6 中,因此如果您正在为 2.5 或更早版本进行开发,则不会有用。

于 2008-12-16T14:58:08.003 回答
2

也许您可以使用assertisinstance语句的组合。像下面这样的东西我认为是一种更 Pythonic 的方式,因为只要你的输入不符合你的要求,你就会抛出一个异常。不幸的是,我没有看到比您的有效数字更好的定义。也许有人会提出一个更好的主意。

number = (float, int, long)
assert isinstance(mydata, (float, int, long))
于 2008-12-16T14:19:43.807 回答
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

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

There's no point in overvalidating inputs, unless you have an algorithm that will not work with some types. These are rare, but some calculations require integers, specifically so they can do integer division and remainder operations. For those, you might want to assert that your values are ints.

于 2008-12-16T19:15:47.093 回答