简体   繁体   English

比较来自 deepcopy 的 Python 对象

[英]Comparing Python objects from deepcopy

Is there a way to compare a Python object with an object generated from a deepcopy?有没有办法将 Python 对象与从深拷贝生成的对象进行比较?

eg:例如:

    import copy 

    original_object = SomeObject()
    cloned_object = copy.deepcopy(original_object)
    assertDeepCopy(original_object, cloned_object)

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. 但请注意,这可能会在许多地方出错:如果对象没有以您喜欢的方式定义== ,您将无法获得所需的答案。

I know it is an old answer, but with Python 3 the previous code didn't work for me, so I updated it in this one that works better for me: 我知道这是一个古老的答案,但是使用Python 3,之前的代码对我来说不起作用,所以我在这个对我更好的更新它:


import logging
log = logging.getLogger(__name__)

...

    def deep_compare(self,left, right, level=0):
        if type(left) != type(right):
            log.info("Exit 1 - Different types")
            return False

        elif type(left) is dict:
            # Dict comparison
            for key in left:
                if key not in right:
                    log.info("Exit 2 - missing {} in right".format(key))
                    return False
                else:
                    if not deep_compare(left[str(key)], right[str(key)], level +1 ):
                        log.info("Exit 3 - different children")
                        return False
            return True
        elif type(left) is list:
            # List comparison
            for key in left:
                if key not in right:
                    log.info("Exit 4 - missing {} in right".format(key))
                    return False
                else:
                    if not deep_compare(left[left.index(key)], right[right.index(key)], level +1 ):
                        log.info("Exit 5 - different children")
                        return False
            return True
        else:
            # Other comparison
            return left == right

        return False

It compares dict, list and any other types that implements the "==" operator by themselves. 它比较了dict,list和任何其他实现“==”运算符的类型。 If you need to compare something else different, you need to add a new branch in the "if tree". 如果您需要比较其他不同的东西,则需要在“if tree”中添加新分支。

Hope that helps. 希望有所帮助。

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

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

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