Python--对象赋值、浅拷贝以及深拷贝之间的区别

时间:2021-01-02 19:49:21

对象赋值、浅拷贝以及深拷贝之间的区别

1.1 对象赋值:

>>> list1 = ["hello", 2018, ["Python", "Java", "C#"]]
>>> id(list1)
2656094454216
>>> list2 = list1
>>> id(list2)
2656094454216

>>> list2[0] = "AA"
>>> list1
['AA', 2018, ['Python', 'Java', 'C#']]
>>> list2
['AA', 2018, ['Python', 'Java', 'C#']]
>>> list2.append("world")
>>> list2
['AA', 2018, ['Python', 'Java', 'C#'], 'world']
>>> list1
['AA', 2018, ['Python', 'Java', 'C#'], 'world']

结论: 对象赋值是对象引用的传递,对赋值后的对象的任何修改都会影响原来的对象。

1.2 浅拷贝

>>> import copy
>>> list1 = ["hello", 2018, ["Python", "Java", "C#"]]
>>> list2 = copy.copy(list1)
>>> id(list1)
2656095918344
>>> id(list2)
2656095919816
>>> 
>>> print([id(e) for e in list1])
[2656094458072, 2656093441840, 2656095918280]
>>> print([id(e) for e in list2])
[2656094458072, 2656093441840, 2656095918280]

>>> list2[0] = "BB"
>>> list1
['hello', 2018, ['Python', 'Java', 'C#']]
>>> list2
['BB', 2018, ['Python', 'Java', 'C#']]
>>>
>>> list2.append("world")
>>> list1
['hello', 2018, ['Python', 'Java', 'C#']]
>>> list2
['BB', 2018, ['Python', 'Java', 'C#'], 'world']
>>> list2[2].append("Javascript")
>>> list1
['hello', 2018, ['Python', 'Java', 'C#', 'Javascript']]
>>> list2
['BB', 2018, ['Python', 'Java', 'C#', 'Javascript'], 'world']

结论: 浅拷贝会创建一个对象,但是对于对象中的元素,浅拷贝会使用原始元素的引用,
当对浅拷贝后对象中的不可变数据类型修改时,会影响原始对象。
当对浅拷贝后对象中的可变数据类型修改时,影响原始对象。

1.3 深拷贝

>>> import copy
>>> list1 = ["hello", 2018, ["Python", "Java", "C#"]]
>>> list2 = copy.deepcopy(list1)
>>> id(list1)
3040963152264
>>> id(list2)
3040963153480
>>> print([id(e) for e in list1])
[3040961695960, 3040928378608, 3040963152072]
>>> print([id(e) for e in list2])
[3040961695960, 3040928378608, 3040963153544]
>>> 
>>> list2[0]="CC"
>>> list1
['hello', 2018, ['Python', 'Java', 'C#']]
>>> list2
['CC', 2018, ['Python', 'Java', 'C#']]
>>> 
>>> list2.append("world")
>>> list1
['hello', 2018, ['Python', 'Java', 'C#']]
>>> list2
['CC', 2018, ['Python', 'Java', 'C#'], 'world']
>>> list2[2].append("Javascript")
>>> list1
['hello', 2018, ['Python', 'Java', 'C#']]
>>> list2
['CC', 2018, ['Python', 'Java', 'C#', 'Javascript'], 'world']

结论: 深拷贝会复制元素中的所有元素,包括子元素,对深拷贝后对象的任何修改都不会影响原始对象