gpt4 book ai didi

python - 为什么以及何时像 Python 中的 `==` 这样的文字比较运算符使用自定义类型而不是内置类型的魔术方法?

转载 作者:行者123 更新时间:2023-12-01 00:04:42 24 4
gpt4 key购买 nike

docs.python.org page on the Python "Data Model" states当文字比较操作中的双方都实现操作的魔术方法时,左操作数的方法将与右操作数一起使用作为其参数:

x<y calls x.__lt__(y), x<=y calls x.__le__(y), x==y calls x.__eq__(y), x!=y calls x.__ne__(y), x>y calls x.__gt__(y), and x>=y calls x.__ge__(y).

以下类包装 builtin tuple并为这些比较运算符之一实现一个神奇的方法来演示这一点:

class eqtest(tuple):
def __eq__(self, other):
print('Equivalence!')

当在比较运算符的左侧使用此类的实例时,它的行为符合预期:

>>> eqtest((1,2,3)) == (1,2,3)
Equivalence!

但是,即使仅使用右侧的实例,自定义类的比较运算符似乎也会被调用:

>>> (1,2,3) == eqtest((1,2,3))
Equivalence!

当显式调用左操作数的魔术方法时,结果也明显不同:

>>> (1,2,3).__eq__(eqtest2((1,2,3)))
True

很容易理解为什么这可能是一个故意的设计选择,尤其是对于子类,以便从稍后定义的类型返回最有可能有用的结果。然而,由于它相当明显地偏离了基本记录的行为,所以很难知道它如何以及为什么以这种方式工作,足以在生产中解释和使用它。

在什么情况下,Python 语言和 CPython 引用实现会颠倒比较运算符的顺序,即使双方都提供了有效结果,这在哪里记录?

最佳答案

comparisons 的规则声明元组不知道如何与其他类型进行比较。 tuplerichcompare执行Py_RETURN_NOTIMPLMENTED。然而,PyObject richcompare检查子类型,例如继承的类,并交换比较顺序(应用对称规则)。

这也记录在您链接的页面中:

If the operands are of different types, and right operand’s type is a direct or indirect subclass of the left operand’s type, the reflected method of the right operand has priority, otherwise the left operand’s method has priority. Virtual subclassing is not considered.

这使得子类能够实现更具体的行为,这些行为可以与以任何一种方式编写的比较一起使用。

关于python - 为什么以及何时像 Python 中的 `==` 这样的文字比较运算符使用自定义类型而不是内置类型的魔术方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60054094/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com