我有一个函数,它需要实数(整数或浮点数)作为输入,我在尝试对它进行数学运算之前验证这个输入。
我的第一直觉是在try-except块中将输入转换为浮点数。
try:
myinput = float(input)
except:
raise ValueError("input is not a well-formed number")
我也可以打电话给isinstance(mydata, (float, int, long) )
但是“所有这些可能是数字”的列表对我来说似乎有点不合适。
最狡猾的方式是什么?我忽略了另一种选择吗?
答案 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)
也许您可以使用assert
和isinstance
语句的组合。
类似下面的内容是我认为更加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
“实数(整数或浮点数)”这个问题通常是无关紧要的。许多东西都是“数字”,可以在数字操作中使用,但不是整数或浮点数。例如,您可能已下载或创建了有理数字包。
输入过高是没有意义的,除非您的算法不适用于某些类型。这些很少见,但有些计算需要整数,特别是它们可以进行整数除法和余数运算。对于那些,您可能想断言您的值是整数。