在docs中明确指出int(number)是地板类型转换:
int(1.23)
1
当且仅当字符串是整数文字时,和int(string)才返回一个int。
int('1.23')
ValueError
int('1')
1
有什么特别原因吗?我发现在一种情况下功能下降而不是另一种情况是违反直觉的。
答案 0 :(得分:124)
没有特殊原因。 Python只是应用其不执行隐式转换的一般原则,隐式转换是众所周知的问题原因,特别是对于新手,在Perl和Javascript等语言中。
int(some_string)
是将字符串转换为整数格式的显式请求;此转换的规则指定该字符串必须包含有效的整数文字表示。 int(float)
是将float转换为整数的显式请求;此转换的规则指定浮点数的小数部分将被截断。
为了让int("3.1459")
返回3
,解释器必须隐式地将字符串转换为float。由于Python不支持隐式转换,因此它选择引发异常。
答案 1 :(得分:76)
这几乎可以肯定是应用Zen of Python中的三个原则:
显式更好隐含。
[...]实用性胜过纯洁
错误不应该以无声方式传递
有些百分比的时间,有人int('1.23')
正在为其用例调用错误的转化,并希望改为float
或decimal.Decimal
。在这些情况下,他们明显更好地获得他们可以修复的即时错误,而不是默默地给出错误的值。
如果做想要将其截断为int,那么首先通过float
传递它然后调用{{1}中的一个来显式地这样做是微不足道的。适当时,},int
,round
,trunc
或floor
。这也使您的代码更加自我记录,防止以后的修改"纠正"通过明确指出舍入值是您想要的内容,假设默默地截断ceil
对int
的调用。
答案 2 :(得分:17)
有时思考实验会很有用。
int('1.23')
失败并显示错误。这是现有行为。int('1.23')
生成1
且没有错误。这就是你提出的建议。通过行为A,可以直接轻松地获得行为B的效果:改为使用int(float('1.23'))
。
另一方面,对于行为B,获得行为A的效果要复杂得多:
def parse_pure_int(s):
if "." in s:
raise ValueError("invalid literal for integer with base 10: " + s)
return int(s)
(即使使用上面的代码,我也没有完全相信没有一些错误处理的错误案例。)
因此,行为A比行为B更具表现力。
要考虑的另一件事:'1.23'
是浮点值的字符串表示。从概念上将'1.23'
转换为整数涉及两次转换(字符串要浮动到整数),但int(1.23)
和int('1')
每次只涉及一次转换。
编辑:
事实上,上面的代码无法处理:* {1}}和1e-2
都是浮点值。
答案 3 :(得分:11)
简单来说 - 它们的功能不同。
它们是2个不同的函数,同名返回一个整数,但它们是不同的函数。
'int'简短且易于记忆,其适用于每种类型的含义对于大多数程序员来说都是直观的,这就是他们选择它的原因。
没有暗示它们提供相同或组合的功能,它们只是具有相同的名称并返回相同的类型。它们可以很容易地被称为'floorDecimalAsInt'和'convertStringToInt',但它们用于'int'因为它易于记忆,(99%)直观且很少发生混淆。
将文本解析为包含小数点(例如“4.5”)的文本的整数将在计算机语言的多数中引发错误,并且预计会通过多数>抛出错误程序员,因为文本值不代表整数,暗示他们提供了错误的数据