Python的对象拷贝分为深拷贝和浅拷贝。
1.深拷贝与浅拷贝的区别
2.实例
浅拷贝实例:
# -*- coding: utf-8 -*-
# @Time : 2022/11/23 20:47
# @File : ShallowCopyDemo.py
# @Software : PyCharm
# 浅拷贝,拷贝的程度浅,只拷贝原数据的首地址,然后通过原数据的首地址,去获取内容。
import copy
class Car:
def __init__(self, brand, price):
self.brand = brand
self.price = price
def __str__(self):
return "汽车品牌:%s,价格:%f" % (self.brand, self.price)
class Person:
def __init__(self, name, gender, age, car):
self.name = name
self.gender = gender
self.age = age
self.car = car
def __str__(self):
return "你好,我叫:%s,性别:%s,年龄:%d \n 汽车信息: %s" % (self.name, self.gender, self.age, self.car)
car1 = Car("BMW", 50000)
p1 = Person("张三", "男", 20, car1)
p2 = copy.copy(p1)
print("p1对象的hashCode:", id(p1), ",p1.car的hashCode:", id(p1.car))
print(p1)
print("p2对象的hashCode:", id(p2), ",p2.car的hashCode:", id(p2.car))
print(p2)
#修改p1对象的姓名和汽车的品牌和价格
p1.name = '张三丰'
car1.brand = "TOYOTA"
car1.price = 10000
print("\n-------修改姓名和汽车信息之后----------\n")
print("p1对象的hashCode:", id(p1), ",p1.car的hashCode:", id(p1.car))
print(p1)
print("p2对象的hashCode:", id(p2), ",p2.car的hashCode:", id(p2.car))
print(p2)
运行结果:
p1对象的hashCode: 2207457154128 ,p1.car的hashCode: 2207457153456
你好,我叫:张三,性别:男,年龄:20
汽车信息: 汽车品牌:BMW,价格:50000.000000
p2对象的hashCode: 2207457155136 ,p2.car的hashCode: 2207457153456
你好,我叫:张三,性别:男,年龄:20
汽车信息: 汽车品牌:BMW,价格:50000.000000
-------修改姓名和汽车信息之后----------
p1对象的hashCode: 2207457154128 ,p1.car的hashCode: 2207457153456
你好,我叫:张三丰,性别:男,年龄:20
汽车信息: 汽车品牌:TOYOTA,价格:10000.000000
p2对象的hashCode: 2207457155136 ,p2.car的hashCode: 2207457153456
你好,我叫:张三,性别:男,年龄:20
汽车信息: 汽车品牌:TOYOTA,价格:10000.000000
我们发现使用copy.copy()实现的是浅拷贝,p1和p2的对象的hashCode不同,说明是两个不同的对象,但是p1和p2里面的car属性仍然指向同一个汽车对象,因此car对象的hashCode相同。这就说明了浅拷贝虽然是重新分配一块内存,创建了一个新的对象,但里面的元素是原对象中各个子对象的引用。
深拷贝实例:
# -*- coding: utf-8 -*-
# @Time : 2022/11/23 21:14
# @File : DeepCopyDemo.py
# @Software : PyCharm
import copy
class Car:
def __init__(self, brand, price):
self.brand = brand
self.price = price
def __str__(self):
return "汽车品牌:%s,价格:%f" % (self.brand, self.price)
class Person:
def __init__(self, name, gender, age, car):
self.name = name
self.gender = gender
self.age = age
self.car = car
def __str__(self):
return "你好,我叫:%s,性别:%s,年龄:%d \n 汽车信息: %s" % (self.name, self.gender, self.age, self.car)
car1 = Car("BMW", 50000)
p1 = Person("张三", "男", 20, car1)
p2 = copy.deepcopy(p1)
print("p1对象的hashCode:", id(p1), ",p1.car的hashCode:", id(p1.car))
print(p1)
print("p2对象的hashCode:", id(p2), ",p2.car的hashCode:", id(p2.car))
print(p2)
p1.name = '张三丰'
car1.brand = "TOYOTA"
car1.price = 10000
print("\n-------修改姓名和汽车信息之后----------\n")
print("p1对象的hashCode:", id(p1), ",p1.car的hashCode:", id(p1.car))
print(p1)
print("p2对象的hashCode:", id(p2), ",p2.car的hashCode:", id(p2.car))
print(p2)
运行结果:
p1对象的hashCode: 2169251435600 ,p1.car的hashCode: 2169251434928
你好,我叫:张三,性别:男,年龄:20
汽车信息: 汽车品牌:BMW,价格:50000.000000
p2对象的hashCode: 2169251438528 ,p2.car的hashCode: 2169251443088
你好,我叫:张三,性别:男,年龄:20
汽车信息: 汽车品牌:BMW,价格:50000.000000
-------修改姓名和汽车信息之后----------
p1对象的hashCode: 2169251435600 ,p1.car的hashCode: 2169251434928
你好,我叫:张三丰,性别:男,年龄:20
汽车信息: 汽车品牌:TOYOTA,价格:10000.000000
p2对象的hashCode: 2169251438528 ,p2.car的hashCode: 2169251443088
你好,我叫:张三,性别:男,年龄:20
汽车信息: 汽车品牌:BMW,价格:50000.000000
我们发现copy.deepcopy实现了深拷贝,p1和p2两者是完全独立的,两者的变化也完全无关。实际上,深拷贝是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。