4

是否有确定两个任意 python 对象相等性的最佳实践?假设我为某种对象编写了一个容器,我需要确定新对象是否等于存储在容器中的旧对象。

问题是我不能使用“is”,因为这只会检查变量是否绑定到同一个对象(但我们可能有一个对象的深层副本,在我的意义上它等于它的原始副本)。我也不能使用“==”,因为其中一些对象返回一个元素相等,比如 numpy 数组。

是否有确定任何类型对象相等性的最佳实践?例如会

repr(objectA)==repr(objectB)

够了吗?

还是常用:

numpy.all(objectA==objectB)

如果 objectA == objectB 评估为“[]”,这可能会失败

干杯,罗伯特

编辑:

好的,关于第三条评论,我更详细地阐述了“你对“平等对象”的定义是什么?”

在强烈的意义上我没有任何平等的定义,我宁愿让对象决定它们是否相等。问题是,据我了解, eq或 == 分别没有公认的标准。该语句可以返回数组或各种东西。

我的想法是让一些运算符在eq和“is”之间将其称为 SEQ(强相等)。SEQ 在某种意义上优于eq,因为它将始终评估为单个布尔值(例如,对于可能意味着所有元素都相等的 numpy 数组)并确定对象是否认为自己相等。但是 SEQ 在内存中不同的对象也可以相等的意义上不如“是”。

4

1 回答 1

2

我建议您编写一个自定义递归相等检查器,如下所示:

from collections import Sequence, Mapping, Set
import numpy as np

def nested_equal(a, b):
    """
    Compare two objects recursively by element, handling numpy objects.

    Assumes hashable items are not mutable in a way that affects equality.
    """
    # Use __class__ instead of type() to be compatible with instances of 
    # old-style classes.
    if a.__class__ != b.__class__:
        return False

    # for types that implement their own custom strict equality checking
    seq = getattr(a, "seq", None)
    if seq and callable(seq):
        return seq(b)

    # Check equality according to type type [sic].
    if isinstance(a, basestring):
        return a == b
    if isinstance(a, np.ndarray):
        return np.all(a == b)
    if isinstance(a, Sequence):
        return all(nested_equal(x, y) for x, y in zip(a, b))
    if isinstance(a, Mapping):
        if set(a.keys()) != set(b.keys()):
            return False
        return all(nested_equal(a[k], b[k]) for k in a.keys())
    if isinstance(a, Set):
        return a == b
    return a == b

可散列对象不以影响相等的方式可变的假设是相当安全的,因为如果将此类对象用作键,它将破坏 dicts 和 set。

于 2013-08-22T10:50:57.033 回答