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

Ste*_*anS 82 python

文档中明确指出int(number)是一种地板类型转换:

int(1.23)
1
Run Code Online (Sandbox Code Playgroud)

当且仅当字符串是整数文字时,int和int(string)才返回一个int.

int('1.23')
ValueError

int('1')
1
Run Code Online (Sandbox Code Playgroud)

这有什么特别的原因吗?我发现在一种情况下功能层是违反直觉的,而不是另一种情况.

hol*_*web 123

没有特别的原因.Python只是应用其不执行隐式转换的一般原则,隐式转换是众所周知的问题原因,特别是对于新手,在Perl和Javascript等语言中.

int(some_string)是将字符串转换为整数格式的显式请求; 此转换的规则指定该字符串必须包含有效的整数文字表示.int(float)是一个将float转换为整数的显式请求; 此转换的规则指定float的小数部分将被截断.

为了int("3.1459")返回3,解释器必须隐式地将字符串转换为float.由于Python不支持隐式转换,因此它选择引发异常.


lvc*_*lvc 75

这几乎可以肯定是应用PythonZen中的三个原则:

显式更好隐含.

[...]实用性胜过纯洁

错误不应该默默地传递

一些百分比的时间,有人正在int('1.23')为他们的用例调用错误的转换,并且想要类似floatdecimal.Decimal相反的东西.在这些情况下,他们明显更好地获得他们可以修复的即时错误,而不是默默地给出错误的值.

在你的情况下需要截断为int,它是微不足道的,将其通过明确地这样做float,然后再调用之一int,round,trunc,floorceil适当的.这也使你的代码更加自我记录,防止后来修改"纠正"假设的静默截断int调用,float通过明确表示舍入值你想要的.


jam*_*lin 17

有时,思考实验可能很有用.

  • 行为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)
Run Code Online (Sandbox Code Playgroud)

(即使使用上面的代码,我也没有完全相信没有一些错误处理的角落情况.)

因此,行为A比行为B更具表现力.

另一件需要考虑的事情是:'1.23'浮点值的字符串表示.转换'1.23'成整数概念性涉及两个转换(串漂浮到整数),但int(1.23)int('1')每个仅涉及一次转化.


编辑:

事实上,上面的代码无法处理的是极端情况:1e-2并且1E-2它们都是浮点值.


小智 11

简单来说 - 它们不是同一个功能.

  • int(十进制)表现为'floor,即敲掉小数部分并返回为int'
  • int(字符串)表现为'此文本描述一个整数,将其转换并返回为int'.

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

'int'简短易记,其意义适用于每种类型,对大多数程序员来说都是直观的,这就是他们选择它的原因.

没有暗示他们提供相同或组合的功能,他们只是具有相同的名称并返回相同的类型.它们可以很容易地被称为'floorDecimalAsInt'和'convertStringToInt',但它们用于'int'因为它易于记忆,(99%)直观且很少发生混淆.

将文本解析为包含小数点(如"4.5")的文本的整数将在大多数计算机语言中引发错误,并且预计会由大多数程序员抛出错误,因为文本值不表示整数并暗示他们提供错误的数据

  • 那么为什么两个"不同的功能"具有相同的名称?听起来像是违反了一些禅宗的废话. (2认同)