python中,经常会需要拷贝特定对象,在此可能就会遇到各种bug,原因就是明白这三种操作的区别,赋值,浅拷贝,深拷贝。

《python里shadowcopy和deepcopy的区别》

赋值(=),浅拷贝(copy)和深拷贝(deepcopy)比较容易区别开的是赋值和两种拷贝的区别,但是对于浅拷贝和深拷贝却不那么容易区分。

赋值语句并不会赋值对象,它仅仅是把变量和对象进行一个绑定。对一个对象的任何改变均会影响另一个对象。而拷贝可以在你改变其中一个对象的时候不改变另一个对象。

深浅拷贝区别在于,浅拷贝做值的变化的时候不会影响另一个对象,但是如果有删除添加的话会影响。深拷贝完全是独立的对象,对一个对象的处理均不会影响另一个对象。

下面以实际代码说明三者区别

代码

    from copy import deepcopy
    dic1 = {'a': 2, 'b': 3, 'c': 4}
    dic2=dic1
    dic1["a"]=1
    print(dic1)
    #{'a': 1, 'b': 3, 'c': 4}
    print(dic2)
    #{'a': 1, 'b': 3, 'c': 4}
    #赋值语句,两者完全一样,同时改变
    dic1 = {'a': [1,2,3], 'b': 3, 'c': 4}
    dic2 = dic1.copy()
    dic1["a"] = [2,3,4]
    print(dic1)
    #{'a': [2, 3, 4], 'b': 3, 'c': 4}
    print(dic2)
    #{'a': [1, 2, 3], 'b': 3, 'c': 4}
    ###改变值不会影响另一个对象的值
    dic1 = {'a': [1,2,3], 'b': 3, 'c': 4}
    dic2 = dic1.copy()
    dic1["a"].append(4)
    print(dic1)
    #{'a': [1, 2, 3, 4], 'b': 3, 'c': 4}
    print(dic2)
    #{'a': [1, 2, 3, 4], 'b': 3, 'c': 4}
    ###由此可见浅拷贝拷贝的是元素和元素引用的对象,如果其子对象是可变的,那么两个对象会同时改变,可参考https://docs.python.org/3/library/copy.html
    dic1 = {'a': [1,2,3], 'b': 3, 'c': 4}
    dic2 = deepcopy(dic1)
    dic1["a"].append(4)
    print(dic1)
    #{'a': [1, 2, 3, 4], 'b': 3, 'c': 4}
    print(dic2)
    #{'a': [1, 2, 3], 'b': 3, 'c': 4}

总结

在实际应用中,赋值语句不要用在callable对象上作为拷贝。

如果对象没有循环引用自身或数据不是非常巨大的情况下,使用深拷贝不会有错。