详解类的浅拷贝和深拷贝的区别

  • Post category:Python

类的浅拷贝和深拷贝的区别

在 Python 中,赋值操作符 = 只会将对象的引用复制给一个新的变量,而实际的对象内容并没有被复制,这就意味着对该对象的更改将被反映到所有引用该对象的变量上。

为了避免此类问题,Python 提供了两种拷贝方式:浅拷贝和深拷贝。本文将详细讲解类的浅拷贝和深拷贝的区别,并提供两条示例说明。

浅拷贝

浅拷贝会复制对象的引用,因此它仅仅复制了对象的第一层内容,也就是说,如果对象包含其他对象的引用,那么浅拷贝仅仅复制了这些引用,而不是实际的对象内容。

以下示例说明了浅拷贝的具体行为:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

class Company:
    def __init__(self, name, ceo):
        self.name = name
        self.ceo = ceo

    def __repr__(self):
        return f'Name: {self.name}, CEO: {self.ceo.name}'

# 定义一个人和一个公司
person = Person('Alice', 25)
company = Company('Apple', person)

# 浅拷贝公司对象
new_company = company
# 修改原始的人对象
person.age = 30

# 查看拷贝后的公司对象
print(new_company)

运行结果如下:

Name: Apple, CEO: Alice

可以看出,由于浅拷贝仅仅复制了对象的引用,因此修改原始的人对象也会反映在拷贝后的公司对象中,导致新的 CEO 年龄也被修改了。

深拷贝

深拷贝会递归地复制对象及其所有引用的对象,因此它会完全复制一个对象及其所有的嵌套内容。

以下示例说明了深拷贝的具体行为:

import copy

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

class Company:
    def __init__(self, name, ceo):
        self.name = name
        self.ceo = ceo

    def __repr__(self):
        return f'Name: {self.name}, CEO: {self.ceo.name}'

# 定义一个人和一个公司
person = Person('Alice', 25)
company = Company('Apple', person)

# 深拷贝公司对象
new_company = copy.deepcopy(company)
# 修改原始的人对象
person.age = 30

# 查看拷贝后的公司对象
print(new_company)

运行结果如下:

Name: Apple, CEO: Alice

可以看出,深拷贝会递归地复制对象及其所有引用的对象,因此拷贝后的公司对象仍然引用着新的 CEO 对象,而没有被原始的人对象所影响。

总结

总的来说,浅拷贝只复制了对象的引用,而深拷贝递归地复制了对象及其所有引用的对象。因此,使用拷贝时需要根据具体情况确定使用哪一种方式,以避免对象状态被意外修改的问题。