Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中int()的反直觉行为_Python - Fatal编程技术网

python中int()的反直觉行为

python中int()的反直觉行为,python,Python,文件中明确指出,int(编号)是地板类型转换: int(1.23) 1 和int(string)返回int当且仅当字符串为整数文本时 int('1.23') ValueError int('1') 1 有什么特别的原因吗?我发现功能楼层在一种情况下是违反直觉的,但在另一种情况下不是。这几乎可以肯定是应用以下三个原则的情况: 显性的比隐性的好 […]实用胜过纯洁 错误永远不应该悄无声息地过去 在某些百分比的时间里,有人在执行int('1.23')时调用了错误的用例转换,并希望使用类似于flo

文件中明确指出,int(编号)是地板类型转换:

int(1.23)
1
和int(string)返回int当且仅当字符串为整数文本时

int('1.23')
ValueError

int('1')
1

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

这几乎可以肯定是应用以下三个原则的情况:

显性的比隐性的好

[…]实用胜过纯洁

错误永远不应该悄无声息地过去

在某些百分比的时间里,有人在执行
int('1.23')
时调用了错误的用例转换,并希望使用类似于
float
decimal.decimal
的转换。在这些情况下,显然最好让他们立即得到可以修复的错误,而不是默默地给出错误的值

如果确实要将其截断为int,则可以先通过
float
将其显式传递,然后根据需要调用
int
round
trunc
floor
ceil
中的一个。这也使您的代码更加自我记录,防止以后的修改“纠正”假设的静默截断
int
调用
float
,方法是明确四舍五入的值是您想要的。

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

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


为了使
int(“3.1459”)
返回
3
,解释器必须隐式地将字符串转换为浮点。因为Python不支持隐式转换,所以它选择引发一个异常。

简单地说,它们不是同一个函数

  • int(decimal)的行为类似于“floor,即去掉小数部分并返回int”
  • int(string)的行为类似于“此文本描述一个整数,将其转换并返回为int”
它们是两个不同的函数,具有相同的名称,返回一个整数,但它们是不同的函数

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

这并不意味着它们提供相同或组合的功能,它们只是具有相同的名称并返回相同的类型。它们可以很容易地被称为“floorDecimalAsInt”和“convertStringToInt”,但它们之所以选择“int”,是因为它很容易记住,(99%)直观,而且很少发生混淆


将文本解析为包含小数点(如“4.5”)的文本的整数将在大多数计算机语言中引发错误,并且大多数程序员都希望引发错误,因为文本值不代表整数,并且暗示它们提供了错误的数据,所以有时候思想实验可能是有用的

  • 行为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)
(即使有了上面的代码,我也不能完全相信它不会出现处理不当的情况。)

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

需要考虑的另一件事:
'1.23'
是浮点值的字符串表示形式。从概念上讲,将
'1.23'
转换为整数需要两次转换(字符串到浮点到整数),但是
int(1.23)
int('1')
每一次只需要一次转换


编辑:


事实上,上述代码无法处理某些特殊情况:
1e-2
1e-2
也都是浮点值。

那么为什么两个“不同的函数”具有相同的名称?听起来像是违反了一些禅宗的胡说八道。因为这个名字对两个不同的函数都有意义,而且很简洁。Int-ify一个小数(floor),将字符串转换为Int(conversion)。从技术上讲,记住
Int
是一种类型(并且是内置的)。它的创建者(
\uuuuuuuuuuuuuuuuuuuuuuuu新的
)采用许多可能的参数类型。它对每种类型的行为都有很好的定义。这个答案完全是错误的
int
实际上不是一个函数,而是一个类型,它的
\uuuuuu new\uuuuuuu
\uuuuuuuuu init\uuuuuuu
方法采用一个字符串或浮点参数,对每个参数进行适当的处理。更准确的说法是,该类型以不同的方式处理这两种参数类型,但只有一种
int
。澄清一下:我不会建议行为B,因为正如您和其他人所说的那样,这很危险。我不确定是否存在比目前更好的解决方案。一种选择是给函数赋予不同的名称,但这只是需要输入更多的内容。在动态类型语言中,让int(1.23)失败并且只让int(不带小数点的浮点)返回整数的明显解决方案是没有意义的。最常见的情况可能是
int('123E-2')
int('1L')
。我认为这些原则早在禅宗形成之前就被采用了,但是