简体   繁体   English

Python平等最佳实践

[英]Best Practice for Equality in Python

is there a best practice to determine the equality of two arbitrary python objects? 是否有最佳实践来确定两个任意python对象的相等性? Let's say I write a container for some sort of object and I need to figure out whether new objects are equal to the old ones stored into the container. 假设我为某种对象编写了一个容器,并且需要弄清楚新对象是否等于存储在容器中的旧对象。

The problem is I cannot use "is" since this will only check if the variables are bound to the very same object (but we might have a deep copy of an object, which is in my sense equal to its original). 问题是我不能使用“ is”,因为这只会检查变量是否绑定到同一对象(但是我们可能有一个对象的深层副本,在我看来,它等于原始对象)。 I cannot use "==" either, since some of these objects return an element-wise equal, like numpy arrays. 我也不能使用“ ==”,因为其中一些对象返回元素方式相等的值,例如numpy数组。

Is there a best practice to determine the equality of any kind of objects? 是否存在确定任何对象相等的最佳实践? For instance would 例如会

repr(objectA)==repr(objectB)

suffice? 满足?

Or is it common to use: 还是通常使用:

numpy.all(objectA==objectB)

Which probably fails if objectA == objectB evaluates to "[]" 如果objectA == objectB评估为“ []”,则可能失败

Cheers, Robert 干杯,罗伯特

EDIT: 编辑:

Ok, regarding the 3rd comment, I elaborate more on "What's your definition of "equal objects"?" 好的,关于第三条评论,我将详细介绍“您对“相等对象”的定义是什么?

In the strong sense I don't have any definition of equality, I rather let the objects decide whether they are equal or not. 从严格的意义上讲,我没有任何关于平等的定义,而是让对象决定它们是否相等。 The problem is, as far as I understand, there is no well agreed standard for eq or ==,respectively. 据我了解,问题是,分别没有针对eq或==的公认标准。 The statement can return arrays or all kinds of things. 该语句可以返回数组或各种各样的东西。

What I have in mind is to have some operator lets call it SEQ (strong equality) in between eq and "is". 我想到的是让一些运算符在eq和“ is”之间将其称为SEQ(强等式)。 SEQ is superior to eq in the sense that it will always evaluate to a single boolean value (for numpy arrays that could mean all elements are equal, for example) and determine if the objects consider themselves equal or not. SEQ始终优于eq ,因为它将始终求值为单个布尔值(例如,对于可能意味着所有元素均相等的numpy数组),并确定对象是否认为自己相等。 But SEQ would be inferior to "is" in the sense that objects that are distinct in memory can be equal as well. 但是,在内存中不同的对象也可以相等的意义上,SEQ不如“ is”。

I suggest you write a custom recursive equality-checker, something like this: 我建议您编写一个自定义的递归相等检查器,如下所示:

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

The assumption that hashable objects are not mutable in a way that affects equality is rather safe, since it would break dicts and sets if such objects were used as keys. 假设可散列对象不能以影响相等性的方式可变的假设是相当安全的,因为如果将此类对象用作键,它将破坏命令和集合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM