类的浅拷贝和深拷贝的区别
在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)])
从输出结果可以看出,当原对象的属性值改变时,新对象的属性值不会改变。因为深拷贝创建了一个新对象,包含了原对象及其子对象的副本,所以即使原对象的属性值改变了,新对象的属性值也不会改变。
总结
浅拷贝只是复制了对象的引用,而不是对象本身,因此新对象和原对象共享同一块内存空间,当原对象的属性值改变时,新对象的属性值也会改变。
深拷贝创建了一个新对象,包含了原对象及其子对象的副本,而不仅仅是对象的引用,因此新对象和原对象不共享同一块内存空间,当原对象的属性值改变时,新对象的属性值不会改变。