我正在辅导邻居的孩子,我们正在探索int()
函数,然后将它与input()一起使用 - 它返回一个字符串。我们尝试了以下方法:
int(5)
int(5.5)
int('5')
int('5.5')
前三个按预期返回5
;最后一个抛出错误
ValueError:基数为10的int()的无效文字:'5.5'
考虑到前三行的行为,我如何向14岁的人解释错误(背景=说4种语言,但数学不是那么热)?
更新
C#表现出相同的行为:
Convert.ToInt32("5.5");
抛出错误
输入字符串的格式不正确。
答案 0 :(得分:54)
简而言之:因为这就是规范所说的。无论如何,这是一种有用的心态。 ; - )
现在,规范为何如此说明?函数只能接受有限数量的类型作为有效输入。 int
函数试图涵盖两种不同的用例:
int
float
值转换为int
,将其截断* 第三个用例“将浮点数的字符串表示转换为int
”不在规范中,因为语言设计者决定不介绍它。这似乎是一个合理的决定,因为他们需要在功能将会和不会接受的类型上绘制线。浮点数的字符串表示应由float
解析,而不是int
。
*实际上:任何具有__int__
方法的对象,但让它保持简单。
作为一个反例,在PHP中你可以尝试将任何字符串强制转换为int
,它会尝试为你提供最佳匹配:
php > echo (int)'3.14';
3
php > echo (float)'3.14';
3.14
php > echo (int)'3 little pigs';
3
php > echo (int)'there are 3 little pigs';
0
老实说,这是一种相当疯狂的行为,尤其是最后一次行为。 Python有一个严格的(呃)类型系统;如果你试图将字符串解析为int
,它必须是整数的完全有效表示,而不仅仅是某处包含可以解释为数字的东西。
答案 1 :(得分:30)
该行的问题在于涉及两次转换:
"5.5" (string) -> 5.5 (float) -> 5 (int)
Python中的转换运算符一次只应用一个转换,而不是两个链接,因为在许多情况下这可能会变得混乱。
解决方案是应用两个嵌套转换:
int(float("5.5"))
答案 2 :(得分:5)
您可以参考docs:
class int(x=0) class int(x, base=10)
返回由数字或字符串x构造的整数对象,如果没有给出参数,则返回0。如果x是数字,则返回
x.__int__()
。 对于浮点数,此截断为零。如果x不是数字或者给定了base,那么x必须是以基数表示整数字面值的字符串,字节或bytearray实例 base。可选地,文字可以以+或 - 开头(没有空格 介于两者之间)并被空白包围。 base-n文字由 数字0到n-1,a到z(或A到Z)的值为10到35。 默认基数为10.允许的值为0和2-36。 Base-2,-8, 和-16文字可以选择以0b / 0B,0o / 0O或者前缀为前缀 0x / 0X,与代码中的整数文字一样。基数0表示解释 完全作为代码文字,以便实际的基数是2,8,10或16, 所以int(' 010',0)不合法,而int(' 010')也是 as int(' 010',8)。
整数类型在数值类型中描述 - int,float,complex。
(强调我的)
参考文档教导,在编程中,没有什么是真的是随意的,编译器/解释器只是遵循规则。
答案 3 :(得分:3)
我想我会说int(5.5)
和int('5.5')
都不是你应该做的事情。罗德里戈的回答解释了为什么一个人仍在工作,但在向孩子解释事情的时候,我会尽量让事情尽可能明确,隐含的转换对此没有帮助。
所以,虽然过于明确,但为什么不教这样:
int(floor(float('5.5')))
至少那时候一切都非常明确和明显。
答案 4 :(得分:2)
我会说这背后的问题是运算符重载,因为实际上涉及两个int()函数:一个转换字符串(如果可能),另一个截断浮点数。如果孩子理解类型,我认为她/他也会理解重载是什么。
答案 5 :(得分:1)
尝试解释包含数字的字符串,就像它被写成单词一样。
int(5)
int(5.5)
起作用,因为Python的int()函数“看到”它作为数字并且取整个数字部分,就像另一个孩子一样,对浮点/小数位置一无所知 - >两者都被解释为5,其余部分被忽略。
现在:使用字符串
int('5')
int('5.5')
可以解释为“五”,Python的int()函数知道如何转换为5,但口头“fivepointfive”不是我们孩子听过的,不知道浮点数。 (int()函数是这里的孩子)
一个很好的问题,也是一个常见的挑战,尝试用这种方式解释。
答案 6 :(得分:1)
你的(虚构的)函数将猫的图片作为参数,你试图将它传递给一只真正的猫。在函数知道如何处理它之前,需要首先从cat到cat的图片进行转换。