Python比较int和float时什么时候进行类型转换?

When does Python perform type conversion when comparing int and float?

当我比较具有相同值的 intfloat 对象时,为什么 Python return True

例如:

>>> 5*2 == 5.0*2.0
True

这可不像类型转换那么简单。

10 == 10.0 委托给参数的 __eq__ 方法,首先尝试 (10).__eq__(10.0),然后 (10.0).__eq__(10) 如果第一次调用 returns NotImplemented.它不尝试转换类型。 (从技术上讲,方法查找使用绕过实例 __dict__ 条目和 __getattribute__/__getattr__ 覆盖的特殊例程,因此它不完全等同于自己调用方法。)

int.__eq__ 不知道如何处理浮点数:

>>> (10).__eq__(10.0)
NotImplemented

但是float.__eq__知道如何处理整数:

>>> (10.0).__eq__(10)
True

float.__eq__ 也不只是在内部执行演员表。它有 over 100 lines 代码来处理 float/int 比较,没有未经检查的转换可能引入的舍入错误。 (如果 C 级比较例程不必处理 >>=<<=,则其中一些可以简化。)

== 

是比较运算符

你实际上是在问口译员你表达的两边是否相等

换句话说,您要求它 return 一个布尔值,而不是转换数据类型。如果你想转换数据类型,你必须在你的代码中隐式地这样做。

Objects of different types, except different numeric types, never compare equal.

并且:

Python fully supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the “narrower” type is widened to that of the other, where integer is narrower than floating point, which is narrower than complex. Comparisons between numbers of mixed type use the same rule.

https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex

比较逻辑由每个类型的__eq__ method实现。并且标准数字类型的实现方式是它们支持彼此之间的比较(和算术运算)。 Python 作为一种语言从不进行隐式类型转换(就像 Javascript 的 == 运算符会进行隐式类型转换)。

答案很简单,语言就是这样设计的。以下是支持这一点的文档的摘录:

6.10.1 Value Comparisons

Numbers of built-in numeric types (Numeric Types — int, float, complex) and of the standard library types fractions.Fraction and decimal.Decimal can be compared within and across their types, with the restriction that complex numbers do not support order comparison.

换句话说,我们希望具有相同值的不同数值类型相等。

PEP 20

Special cases aren't special enough to break the rules.

Although practicality beats purity.

除了让大多数常见情况变得困难之外,让数字类型不可比较还有什么好处?

== 运算符只比较值而不比较类型。您可以使用 'is' 关键字来实现与在其他语言中使用 === 相同的效果。例如

5 is 5.0

returns 假

您可以查看 the source code CPython 实现。

此函数前面有解释如何尝试转换的注释:

/* Comparison is pretty much a nightmare.  When comparing float to float,
 * we do it as straightforwardly (and long-windedly) as conceivable, so
 * that, e.g., Python x == y delivers the same result as the platform
 * C x == y when x and/or y is a NaN.
 * When mixing float with an integer type, there's no good *uniform* approach.
 * Converting the double to an integer obviously doesn't work, since we
 * may lose info from fractional bits.  Converting the integer to a double
 * also has two failure modes:  (1) an int may trigger overflow (too
 * large to fit in the dynamic range of a C double); (2) even a C long may have
 * more bits than fit in a C double (e.g., on a 64-bit box long may have
 * 63 bits of precision, but a C double probably has only 53), and then
 * we can falsely claim equality when low-order integer bits are lost by
 * coercion to double.  So this part is painful too.
 */

不保证其他实现遵循相同的逻辑。

来自documentation

Python fully supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the “narrower” type is widened to that of the other, where plain integer is narrower than long integer is narrower than floating point is narrower than complex. Comparisons between numbers of mixed type use the same rule.

据此5*2加宽为10.0等于10.0 如果您正在比较混合数据类型,那么将根据具有长范围的数据类型的基础来考虑结果,因此在您的情况下,浮点范围大于 int 最大浮点数可以是 --> 1.7976931348623157e+308 int 最大数量可以是 --> 9223372036854775807

谢谢