Python平等的最佳实践

时间:2013-08-22 09:44:57

标签: python equality

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

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

是否有最佳做法来确定任何类型对象的相等性? 例如

repr(objectA)==repr(objectB)

足够?

或者使用是否常见:

numpy.all(objectA==objectB)

如果objectA == objectB评估为“[]”

,则可能失败

干杯, 罗伯特

编辑:

好的,关于第3条评论,我详细说明了 “你对”平等对象“的定义是什么?”

在强烈意义上,我没有任何相等的定义,我宁愿让对象决定它们是否相等。问题是,据我所知, eq 或==没有完全一致的标准。该语句可以返回数组或各种事物。

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

1 个答案:

答案 0 :(得分: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并设置这些对象是否被用作键。