Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing Python objects from deepcopy

Is there a way to compare a Python object with an object generated from a deepcopy?

e.g.:

    import copy 

    original_object = SomeObject()
    cloned_object = copy.deepcopy(original_object)
    assertDeepCopy(original_object, cloned_object)
like image 677
Bradford Wade Avatar asked Oct 21 '22 04:10

Bradford Wade


2 Answers

This solution allows you to to deep compare objects, dicts, lists and primitives. And it allows you to exclude keys from the comparison.

I thought this might be helpful to some people looking for deep compare with object support :)

def deep_compare(left, right, excluded_keys = []):
    # convert left and right to dicts if possible, skip if they can't be converted
    try: 
        left = left.__dict__
        right = right.__dict__
    except:
        pass

    # both sides must be of the same type 
    if type(left) != type(right):
        return False

    # compare the two objects or dicts key by key
    if type(left) == dict:
        for key in left:
            # make sure that we did not exclude this key
            if key not in excluded_keys:
                # check if the key is present in the right dict, if not, we are not equals
                if key not in right:
                    return False
                else:
                    # compare the values if the key is present in both sides
                    if not deep_compare(left[key], right[key], excluded_keys):
                        return False

        # check if any keys are present in right, but not in left
        for key in right:
            if key not in left and key not in excluded_keys:
                return False
        
        return True

    # check for each item in lists
    if type(left) == list:
        # right and left must have the same length
        if len(left) != len(right):
            return False

        # compare each item in the list
        for index in range(len(left)):
            if not deep_compare(left[index], right[index], excluded_keys):
                return False

    # do a standard comparison
    return left == right
like image 96
Levi Hechenberger Di Valentino Avatar answered Oct 22 '22 17:10

Levi Hechenberger Di Valentino


This is what I believe you're asking for:

def deep_compare(left, right):
    try:
        if not left.__dict__:
            return left == right

        for key in left.__dict__:
            if key not in right.__dict__:
                return false
            else:
                return deep_compare(left[key], right[key])
    except (AttributeError, TypeError):
        return left == right 

However, note that this can go wrong in a number of places: if the objects don't define == in a way that you like, you won't get the answer that you want.

like image 32
Patrick Collins Avatar answered Oct 22 '22 16:10

Patrick Collins