许多人都发表了这样的评论,但没有人提出它为什么不好的原因。
如何捕获用户输入错误?等待其他地方的某些代码,然后引发异常?"为什么不立即发现错误会更好?
例如,(ab)用户在17.6中输入预期的整数响应。对float
的预期类型获取int
的类型显然是错误的(只是为了清楚?)。
或者说,(ab)用户甚至为预期的float
输入17/6。 17/6 是一个float
,所以如果等待数据到达实际使用的位置,就很难发现这个错误。
我不明白这个前提。
=========================== 以下是基于许多(非常好的)回复的编辑 - 并且感谢所有这些回复!
首先,我认为所有编码样式都是基于那些根据他们遇到的错误学会了这些意见的人的意见。所以,是的,根据定义,因为这是一个编码风格的问题,所有答案都可能基于意见或在那里带来的经验。
其次,输入后的测试类型,在函数中,现在是我从评论中理解的东西。非常感谢您的示例和解释。
第三,也许"类型测试很糟糕"正如许多评论所指出的那样,意识形态应该在某种程度上阐述,以表示测试后的输入。这是对我所做的搜索的许多回复中陈述的一揽子声明,试图测试我的代码中获得的人工输入。
再一次,非常感谢所有人共享的知识。
答案 0 :(得分:3)
作为几个例子,
假设您需要将文件传递给函数。你真正想要的是一个类文件对象,这意味着你可以在你喜欢的任何对象上实现.write()
方法并将其传递给函数。检查对象的类型是不好的,您需要验证对象是否具有正确的接口。
让我们假设你从一个numpy数组中取出一些数字并用JSON将它们序列化到磁盘。糟糕!
import numpy, json
a = numpy.array([1, 2, 3], numpy.uint16)
print(json.dumps(a[0]))
运行时,
TypeError: 1 is not JSON serializable
什么?显然,1 是 JSON可序列化的,但它是一个具有不同类型的1。试想一下跟踪那种错误。谁知道自从那个数字处于一个阵容中以来已经有多久了!
所以你想做输入验证,是的,因为这会在它们成为问题之前更早地发现错误。但是,您不希望仅仅依赖于对象的类型,因为Python中的类型系统不表示您实际需要的输入约束。
在其他语言中,约定是使用类型系统表达对输入的约束。例如,类文件对象可以实现为类型类或具有此类概念的语言中的接口。
那就是说,如果你真的需要一个int
,我认为类型检查很好。
答案 1 :(得分:2)
要扩展Simeon Visser和我的评论,应始终进行输入验证。但是,使用类型检查来验证输入并不是一个好主意,因为这意味着你可能在任意数据上使用eval()
,这是一个巨大的安全漏洞,正如SO成员Ned Batchelder的文章{{3}所解释的那样。 }
应尽快执行输入验证,以便您可以保证程序的内部功能仅接收不需要进一步验证的合理数据。让每个函数验证其参数都是低效的,并使代码膨胀,使其更难以阅读和维护。类比:输入验证程序就像程序入口处的安全防护。数据通过安全检查后,程序中的所有函数都可以认为数据是安全的。
Duck输入允许您编写对他们期望的数据类型宽松的函数。这使它们更加灵活和可重复使用。因此(例如)执行算术的函数不应该关心它们接收的数据类型,只关心数据支持函数执行的算术运算。这使得您不仅可以在整数或浮点数上使用相同的函数,还可以在更奇特的数值类型(如分数或甚至多项式)上使用相同的函数。
答案 2 :(得分:1)
我不同意类型检查是一个坏主意的问题,我不确定为什么有人会发表这样的声明。我发现类型检查相当重要,Python提供了许多内置函数来解决类型相关的问题。 类型的使用通过消除运行时检查来确定值的类型,从而提高了代码执行的安全性和性能。
Python是一种dynamically typed语言(并且是解释的),与静态类型语言(通常是编译的)形成对比。根据Python 3.5和PEP 484,语言在其源代码中支持type hints,而字节码解释器或编译器尚未支持它。
您可能希望阅读Duck Typing这一术语,还可以查看type()
函数和其他type related functions。
用你的例子说明:
>>> i = 17
>>> type(i) # get the type of variable i
<class 'int'>
>>> float(i) # convert int to float
17.0
>>> f = 17.6
>>> type(f) # get the type of variable f
<class 'float'>
>>> type(f) is float # check if variable f is a float
True
>>> type(f) is int # check if variable f is an int
False
>>> int(f) # convert float to int
17
>>> s = "17.6"
>>> type(s) # get the type of variable s
<class 'str'>
>>> float(s) # convert string s to float (or exception if not possible)
17.6
>>> type( float(s) )
<class 'float'>