int()在python中的违反直觉的行为

在文档中明确指出,int(数字)是一种地板types转换:

int(1.23) 1 

和int(string)返回一个int当且仅当该string是一个整数文字。

 int('1.23') ValueError int('1') 1 

这有什么特别的理由吗? 我觉得这个function在一种情况下是有违直觉的,而不是在另一种情况下。

没有特别的理由。 Python只是简单地应用其不执行隐式转换的一般原则,这是众所周知的问题原因,特别是对于像Perl和Javascript这样的语言的新手而言。

int(some_string)是将string转换为整数格式的显式请求; 此转换的规则指定该string必须包含有效的整数字面值expression式。 int(float)是将float转换为整数的明确请求; 此转换的规则指定浮点的小数部分将被截断。

为了使int("3.1459")返回3 ,解释器将不得不隐式地将string转换为浮点数。 由于Python不支持隐式转换,因此它select引发exception。

这几乎可以肯定是一个应用Python的禅的三个原则的例子:

显式是更好的隐式。

实用性胜过纯净

错误不应该默默通过

某些时间百分比,某人在做int('1.23')的时候,正在为它们的用例调用错误的转换,并且想要一些像float或者decimal.Decimal东西。 在这些情况下,他们立即得到一个可以解决的错误显然是更好的,而不是默默地给出错误的价值。

如果你想把它截断为一个int,那么通过首先将它传递给float ,然后根据需要调用introundtruncfloor或者ceil来明确地做到这一点是微不足道的。 这也使得你的代码更加自我logging,防止后来的修改“纠正”一个假设的静静地截断int调用float通过明确说明四舍五入的值你想要的。

有时候思想实验可能会有用。

  • 行为A: int('1.23')失败,出现错误。 这是现有的行为。
  • 行为B: 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) 

(甚至在上面的代码中,我也没有完全的信心,认为没有任何error handling的情况)。

行为A因此比行为B更具performance力

另一件要考虑的事情是: '1.23'是一个浮点值的string表示forms。 将'1.23'转换为一个整数在概念上涉及两次转换(将string转换为整数),但是int(1.23)int('1')每次只涉及一次转换。


编辑:

事实上,上面的代码不能处理的angular落情况: 1e-21E-2也都是浮点值。

简而言之 – 它们不是相同的function。

  • int(十进制)performance为“floor”,即敲除小数部分并返回为“int”
  • int(string)performance为“这个文本描述一个整数,将其转换并返回为int”。

它们是2个不同的函数,它们具有相同的名称 ,它们返回一个整数,但它们是不同的函数

“int”简短易记,适用于每种types的含义对于大多数程序员来说是直观的,这就是为什么他们select它。

没有暗示他们提供相同或组合的function,他们只是具有相同的名称并返回相同的types。 他们可以很容易地被称为“floorDecimalAsInt”和“convertStringToInt”,但他们去了“int”,因为它很容易记住,(99%)直观和混乱很less发生。

将文本parsing为包含小数点(例如“4.5”)的文本的整数将在大多数计算机语言中引发错误,并且被大多数程序员抛出错误,因为文本值并不代表整数并且意味着他们提供的是错误的数据