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

  • Post category:Python

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

在Python中,类的拷贝分为浅拷贝和深拷贝两种方式。

浅拷贝

浅拷贝只是复制了对象的引用,而不是对象本身。新的对象和原对象指向同一块内存空间,因此当原对象的属性值发生变化时,新对象的属性值也会随之改变。

以下是一个浅拷贝的示例:

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

    def __repr__(self):
        return f"Person(name={self.name}, age={self.age})"

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

    def __repr__(self):
        return f"Company(name={self.name}, employees={self.employee_list})"

if __name__ == "__main__":
    employees = [Person("John", 25), Person("Jane", 30)]
    company1 = Company("Company1", employees)
    company2 = copy.copy(company1)

    company1.name = "Company1_change"
    company1.employee_list[0].name = "John_change"
    print(company1)
    print(company2)

输出结果为:

Company(name=Company1_change, employees=[Person(name=John_change, age=25), Person(name=Jane, age=30)])
Company(name=Company1, employees=[Person(name=John_change, age=25), Person(name=Jane, age=30)])

从输出结果可以看出,当原对象的属性值改变时,新对象的相应属性值也会改变。因为浅拷贝只是复制了引用,所以这种情况下,新对象引用了与原对象相同的列表对象。

深拷贝

深拷贝创建了一个新对象,包含了原对象及其子对象的副本,而不仅仅是对象的引用。因此当原对象的属性值改变时,新对象的属性值不会改变。

以下是一个深拷贝的示例:

import copy

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

    def __repr__(self):
        return f"Person(name={self.name}, age={self.age})"

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

    def __repr__(self):
        return f"Company(name={self.name}, employees={self.employee_list})"

if __name__ == "__main__":
    employees = [Person("John", 25), Person("Jane", 30)]
    company1 = Company("Company1", employees)
    company2 = copy.deepcopy(company1)

    company1.name = "Company1_change"
    company1.employee_list[0].name = "John_change"
    print(company1)
    print(company2)

输出结果为:

Company(name=Company1_change, employees=[Person(name=John_change, age=25), Person(name=Jane, age=30)])
Company(name=Company1, employees=[Person(name=John, age=25), Person(name=Jane, age=30)])

从输出结果可以看出,当原对象的属性值改变时,新对象的属性值不会改变。因为深拷贝创建了一个新对象,包含了原对象及其子对象的副本,所以即使原对象的属性值改变了,新对象的属性值也不会改变。

总结

浅拷贝只是复制了对象的引用,而不是对象本身,因此新对象和原对象共享同一块内存空间,当原对象的属性值改变时,新对象的属性值也会改变。

深拷贝创建了一个新对象,包含了原对象及其子对象的副本,而不仅仅是对象的引用,因此新对象和原对象不共享同一块内存空间,当原对象的属性值改变时,新对象的属性值不会改变。