【发布时间】:2016-07-05 06:07:31
【问题描述】:
docs 中明确说明 int(number) 是地板类型转换:
int(1.23)
1
并且 int(string) 返回一个 int 当且仅当字符串是一个整数文字。
int('1.23')
ValueError
int('1')
1
有什么特别的原因吗?我发现函数在一种情况下落地,但在另一种情况下不落地,这违反直觉。
【问题讨论】:
标签: python
docs 中明确说明 int(number) 是地板类型转换:
int(1.23)
1
并且 int(string) 返回一个 int 当且仅当字符串是一个整数文字。
int('1.23')
ValueError
int('1')
1
有什么特别的原因吗?我发现函数在一种情况下落地,但在另一种情况下不落地,这违反直觉。
【问题讨论】:
标签: python
没有特殊原因。 Python 只是应用其不执行隐式转换的一般原则,这是众所周知的问题原因,尤其是对于 Perl 和 Javascript 等语言的新手而言。
int(some_string) 是将字符串转换为整数格式的显式请求;此转换的规则指定字符串必须包含有效的整数文字表示。 int(float) 是将浮点数转换为整数的显式请求;此转换的规则指定将截断浮点数的小数部分。
为了让int("3.1459") 返回3,解释器必须将字符串隐式转换为浮点数。由于 Python 不支持隐式转换,因此它选择引发异常。
【讨论】:
type(3) 返回<type int>。但是,python 并没有抱怨float("3")。 python不是隐式将字符串转换为int然后再转换为float吗?
这几乎可以肯定是应用Zen of Python 中的三个原则的案例:
显式最好是隐式。
[...] 实用胜过纯粹
错误不应该默默地过去
在某些情况下,执行int('1.23') 的人会为他们的用例调用错误的转换,而是想要float 或decimal.Decimal 之类的东西。在这些情况下,他们显然最好立即获得可以修复的错误,而不是默默地给出错误的值。
如果您确实想要将其截断为 int,通过首先将其传递给 float,然后调用 int、@ 中的一个来显式地这样做是微不足道的987654327@、trunc、floor 或 ceil(视情况而定)。这也使您的代码更具自我记录性,防止以后的修改“纠正”假设的静默截断 int 调用 float 通过明确舍入值 你想要什么.
【讨论】:
有时思想实验会很有用。
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') 都只涉及一次转换。
编辑:
确实,上面的代码无法处理某些极端情况:1e-2 和 1E-2 也是浮点值。
【讨论】:
int('123E-2') 或int('1L')。
简单来说 - 它们不是同一个功能。
它们是两个不同的函数,同名返回一个整数,但它们是不同的函数。
'int' 简短易记,适用于每种类型的含义对大多数程序员来说都是直观的,这就是他们选择它的原因。
这并不意味着它们提供相同或组合的功能,它们只是具有相同的名称并返回相同的类型。它们可以很容易地称为“floorDecimalAsInt”和“convertStringToInt”,但他们选择“int”是因为它易于记忆、(99%)直观且很少发生混淆。
将包含小数点(例如“4.5”)的文本解析为整数会在大多数计算机语言中引发错误,并且预计会在大多数中引发错误em> 的程序员,因为文本值不代表整数并暗示他们提供了错误的数据
【讨论】:
int 是一种类型(并且是内置类型)可能会有所帮助。它的创建者 (__new__) 采用了许多可能的参数类型。它对每种类型的行为都是明确定义的。
int 实际上不是一个函数而是一个类型,其__new__ 和__init__ 方法接受一个字符串或浮点参数,并适当地处理每一个。更准确地说,该类型对两种参数类型的处理方式不同,但只有一个 int。