Python中直接赋值、浅拷贝和深拷贝的区别

Python中直接赋值、浅拷贝和深拷贝的区别

    • 1 Python中直接赋值、浅拷贝和深拷贝的概念
    • 2 浅拷贝和深拷贝在内存地址上的区别
    • 3 举例说明
    • 参考资料

1 Python中直接赋值、浅拷贝和深拷贝的概念

直接赋值: 创建一个别名,本质上是对象引用。
浅拷贝: 拷贝父对象,而不会拷贝父对象内部的子对象。操作上,重新分配一块内存用于创建父对象,内部包含子对象的引用。
深拷贝: 完全拷贝父对象和子对象。新对象与原对象不再有关系。

Python中直接赋值、浅拷贝和深拷贝的区别_第1张图片

2 浅拷贝和深拷贝在内存地址上的区别

此处引用 时代&信念 的博文内容。

浅拷贝:

父对象数据类型 子对象数据类型 父对象地址 子对象地址
可变 可变 改变 相同
可变 不可变 改变 相同
不可变 可变 相同 相同
不可变 不可变 相同 相同

结论: 使用浅拷贝时,子对象相同;如果父对象为可变数据类型,则父对象不同,如果父对象为不可变数据类型,则父对象相同。

深拷贝:

父对象数据类型 子对象数据类型 父对象地址 子对象地址
可变 可变 改变 改变
可变 不可变 改变 相同
不可变 可变 改变 改变
不可变 不可变 相同 相同

结论: 使用深拷贝时,如果子对象为可变数据类型,父对象和子对象都不同;如果子对象为不可变类型,子对象相同,父对象根据父对象的数据类型而定。

3 举例说明

import copy

a = [1, ['a', 'b']]
b = a
c = a.copy()
d = copy.deepcopy(a)

print(a is b)
print(a is c)
print(a is d)

print(a[0] is b[0])
print(a[0] is c[0])
print(a[0] is d[0])

a.append(5)   # 增加父对象中的元素
print(a)
print(b)
print(c)
print(d)

a[0] = 6   # 修改父对象中的元素
print(a)
print(b)
print(c)
print(d)

a[1].append('c')   # 增加子对象中的元素
print(a)
print(b)
print(c)
print(d)

''' 输出结果 '''
True      # b和a指向同一个父对象
False     # c、d与a指向不同的父对象
False
True
True      # a、c指向相同的子对象
False
[1, ['a', 'b'], 5]
[1, ['a', 'b'], 5]
[1, ['a', 'b']]
[1, ['a', 'b']]
[6, ['a', 'b'], 5]   # a[0]指向新的子对象
[6, ['a', 'b'], 5]
[1, ['a', 'b']]      # c[0]仍指向原来的子对象
[1, ['a', 'b']]
[6, ['a', 'b', 'c'], 5]
[6, ['a', 'b', 'c'], 5]
[1, ['a', 'b', 'c']]   # c和a的子对象相同
[1, ['a', 'b']]

注意: 在Python中,根本没有办法删除值。 使用 del 只能删除对象名称。当一个值(放在内存空间)没有对象名称与之关联时,Python解释器会直接将其删掉,称为 “垃圾收集”。

x = 1
y = x
z = x
x += 1        # x指向新的值
del y         # 删除变量名y
print(x, z)   # z指向的值(内存空间)还在原位
print(y)

''' 输出结果 '''
2 1
Traceback (most recent call last):
  File "/home/.../test.py", line 7, in <module>
    print(y)
NameError: name 'y' is not defined

参考资料

菜鸟教程. Python 直接赋值、浅拷贝和深度拷贝解析.
xzw96. Python 深拷贝和浅拷贝详解. CSDN博客.
时代&信念. Python中的浅拷贝和深拷贝(一看就懂!!!). CSDN博客.

你可能感兴趣的:(零碎的知识,python,开发语言)