【问题标题】:How to call the default string equality function in Python?如何在 Python 中调用默认的字符串相等函数?
【发布时间】:2019-08-19 01:05:19
【问题描述】:

我会假设:

import numpy as np
a = np.array(["a", "b", "c"])
print(a == "abc")
print("abc" == a)

输出

[False False False]
False

,因为后面的比较应该使用字符串相等的定义,而前者应该使用 NumPy 数组的相等定义。

真正的输出是:

[False False False]
[False False False]

为什么会发生这种情况[1]以及如何防止它[2]?

[1] 即为什么是str.__eq__NotImplemented

[2] 即如果 np.ndarray.__eq__ 不被实现,如何调用执行的相等检查?

[编辑] 这个问题被标记为可能与comparing a string 1-d numpy array elementwise 重复,但事实并非如此,因为那里提出了完全相反的问题(基本上如何使用np.ndarray.__eq__),而且 [1] 和 [2] 都不是都讨论过了。

【问题讨论】:

标签: python python-3.x operators equality


【解决方案1】:

我将简要介绍正在发生的事情:

'abc' == a 表达式将首先调用'abc'.__eq__(a),但如果传递的参数不是str 类型,str.__eq__ 将返回NotImplemented。作为后备,Python 将改为调用 a.__eq__('abc')。将比较委托给另一个对象上的反射方法的原因是因为该对象实际上可能实现它。

在这种情况下,np.array.__eq__ 实际上可以通过逐个元素比较来处理字符串,并返回[False, False, False]。根据data model docs,这是可以接受的:__eq__ 方法不需要返回bool 值。无论变量在等式中的位置如何,都会发生这种行为。

现在,具体回答您的问题:

  • 为什么是str.__eq__NotImplemented

这只是str.__eq__ 的预期行为,正如documentation 所述:

不同类型的对象,除了不同的数值类型,从不比较相等

换句话说,str.__eq__ 仅针对 str 参数实现。将str 类型与其他不同类型的对象进行比较需要某种隐式类型转换,这将违背 Python 的禅意:

显式优于隐式

  • 如果不实现np.ndarray.__eq__,如何调用执行的相等检查?

如果相等的两边都没有实现__eq__,Python 将做一个最后的回退到id(a) == id('abc'),它将比较两个对象在内存中的地址。这将只返回False,因为每个id 调用将返回一个int,对于每个对象来说都是不同的。所以,如果你需要的话,你可以使用id(a) == id('abc')

【讨论】:

  • 默认字符串比较不是按 id 比较:a = "abcd"[0:3]; b = "abc"; print(a == b); print(id(a) == id(b)) 例如打印True\nFalse
  • "abcd"[0:3]"abc" 都是 str 类型,与字符串参数的默认字符串比较是 str.__eq__。不会发生id 比较。 id 比较失败,因为它比较的是内存中的地址,对于字符串等不可变类型可能相同也可能不同(例如:单个字符字符串将具有相同的 id:id("abcd"[0]) == id("a"))。
  • 啊,str.__eq__ 只为非字符串类型提供NotImplemented!这就向我解释了。谢谢。
猜你喜欢
  • 2013-03-13
  • 2018-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多