mypy:为什么“int”是“float”的子类型?

问题描述 投票:0回答:2

为什么“mypy”将“int”视为“float”的子类型?子类型应支持其父类型的所有方法,但“float”具有“int”不支持的方法:

测试.py:

def f(x : float) -> bool:
    return x.is_integer()

print(f(123.0))
print(f(123))

静态类型检查器接受为“float”参数传递“int”参数:

(3.8.1) myhost% mypy test.py
Success: no issues found in 1 source file

但这并不能保证运行时没有错误:

(3.8.1) myhost% python test.py
True
Traceback (most recent call last):
  File "test.py", line 5, in <module>
    print(f(123))
  File "test.py", line 2, in f
    return x.is_integer()
AttributeError: 'int' object has no attribute 'is_integer'

因为“float”有额外的方法,而“int”没有。

python python-typing mypy
2个回答
5
投票

'为什么“mypy”将“int”视为“float”的子类型?'

因为到目前为止,实用性在这里被认为胜过纯粹性。 这并不是说不能建议类型定义一种标量类型,该类型包含整数和浮点数,但仅对算术运算有效。

请注意,int / int 在 3.0 中发生了更改,因此 float(int / int) == float(int) / float(int),以使 int 和 float 算术对于相等的 int 和 float 值一致。

另请注意,类型检查通过并不意味着没有运行时错误:被零除和溢出以及许多其他错误仍然是可能的。

更新:从Python 3.8开始,整数现在有一个.as_integer_ratio方法,从3.12开始,整数将获得一个.is_integer方法,只留下专门的.hex和.from_hex作为float-only。


-2
投票

正如@juanpa.arrivillaga所指出的,解释位于https://mypy.readthedocs.io/en/latest/duck_type_compatibility.html

子类型应支持其父类型的所有方法,但“float”具有“int”不支持的方法

int
不是
float
的子类型,因此它不必支持
float
的方法。

该机制很好,因为传递整数值不会导致错误,除非您确实想要像示例中那样。您明确尝试使用不存在的方法。在常见情况下,我们只对数字进行算术运算,因此很少存在问题,您可以按照您所写的添加

.0
来避免它。

在大多数语言中,假设

int
float
的特殊情况是一种常见行为,例如考虑 C++
int
float
的隐式转换。

© www.soinside.com 2019 - 2024. All rights reserved.