Best Equality Practice in Python

is there any best practice for determining the equality of two arbitrary python objects? Let's say I'm writing a container for some kind of object, and I need to find out if the new objects correspond to the old ones stored in the container.

The problem is that I cannot use "is", as this will only check if the variables are associated with the same object (but we can have a deep copy of the object, which in my sense is equal to its original). I also cannot use "==", as some of these objects return evenly, like numpy arrays.

Is there a best practice for determining the equality of any objects? For instance,

repr(objectA)==repr(objectB) 

enough?

Or commonly used:

 numpy.all(objectA==objectB) 

Which probably will not succeed if objectA == objectB evaluates to "[]"

Cheers, Robert

EDIT:

Well, in relation to the third comment, I will talk in detail about "What is your definition of" equal objects? "

In a strong sense, I have no definition of equality; rather, I will let the objects decide whether they are equal or not. The problem is, as I understand it, there is no well-agreed standard for eq or ==, respectively. A statement can return arrays or all kinds of things.

I mean, some operator allows you to call it SEQ (strong equality) between eq and "is". SEQ is superior to eq in the sense that it will always evaluate a single boolean value (for numpy arrays, which can mean that all elements are equal, for example) and determine whether objects are considered equal or not, But SEQ will give way to "is" in that sense that objects that are different in memory can be equal.

+4
source share
1 answer

I suggest you write a custom recursive equality check, 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 hashed objects do not change in a way that affects equality is fairly safe, since it breaks dicts and determines whether such objects will be used as keys.

+2
source

Source: https://habr.com/ru/post/1498347/


All Articles