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

  • Post category:Python

浅拷贝和深拷贝是面向对象编程中重要的概念,用于复制对象。它们的区别在于复制出来的新对象与原对象之间的关系不同。

浅拷贝

浅拷贝是指复制对象时,只会复制对象本身和对象中包含的基本数据类型的值,对于对象里的引用类型的属性,只是复制引用,指向原有对象。这意味着,如果原对象中的引用类型的属性被改变了,浅拷贝出来的新对象中对应的属性也会被改变,因为它们指向的是同一个对象。

下面是一个示例:

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

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

bob = Person('Bob', 25)
alice = Person('Alice', 30)
company = Company('ABC Inc.', [bob, alice])

# 浅拷贝
company2 = company
# 改变原来的对象中的内容
company.name = 'XYZ Inc.'
bob.name = 'Bob Smith'

print(company2.name)
print(company2.employees[0].name)

输出:

XYZ Inc.
Bob Smith

从输出结果中可以看出,复制得到的 company2 对象的 name 属性也被改变了,这是因为 company2company 共享一个对象,当 company 中的属性值发生变化时,因为 company2company 指向的是同一个对象,所有值也会跟着改变。

深拷贝

与浅拷贝不同,深拷贝会复制原对象的所有值,包括基本数据类型和引用类型,所有引用类型的对象也都会被复制一份,新对象和原对象就没有了任何关联。

下面是一个示例:

import copy

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

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

bob = Person('Bob', 25)
alice = Person('Alice', 30)
company = Company('ABC Inc.', [bob, alice])

# 深拷贝
company2 = copy.deepcopy(company)

# 改变原来的对象中的内容
company.name = 'XYZ Inc.'
bob.name = 'Bob Smith'

print(company2.name)
print(company2.employees[0].name)

输出:

ABC Inc.
Bob

从输出结果中可以看出,复制得到的 company2 对象的 name 属性与原来的对象的属性不同,表示拷贝成功,因为它们指向不同的内存地址。此外,即使 company 中的属性被改变,company2 对象的属性依然保持不变。

总结

我们可以发现,浅拷贝和深拷贝两种方式的区别在于:复制的范围不一样。在使用时要根据实际的需求进行选择。

如果原对象中没有引用类型的数据,可以选择浅拷贝,因为不需要考虑到引用类型的数据问题。如果原对象中包含引用类型数据,且需要对新对象进行修改,就应该选择深拷贝。