1、Python 深拷贝与浅拷贝
深拷贝和浅拷贝都是对Python中对象的复制,占用不同的内存空间。深拷贝会完全拷贝父对象及父对象内部的子对象,而浅拷贝会拷贝父对象,但不会拷贝父对象内部的子对象。
浅拷贝会出现的问题就是,有可能拷贝后的对象中内部的子象(例如,字典value是一个类对象或列表,就是内部的子对象),当修改这个子对象时,父对象中内部的子对象,也会被修改,浅拷贝会存在这个问题,因为同一个对象,深拷贝就不会存在这个问题。
2、使用copy()或dict()字典浅拷贝
dic = {"C":1,"Java":2,"Python":4,"CJavaPy":5} d1 = dict(dic)#浅拷贝 print(d1) d2 = dic.copy() #浅拷贝 print(d2)
3、使用deepcopy()字典深拷贝
from copy import deepcopy dic = {"C":1,"Java":2,"Python":4,"CJavaPy":5} d1 = deepcopy(dic) #深拷贝 print(d1)
4、判断深拷贝和浅拷贝
根据深浅拷贝后父对象内部子对象,和拷贝后的子对象内部子对象的区别,来判断是深拷贝还是浅拷贝,代码如下,
1)内部子对象是列表
示例中子对象使用的列表,其它数据集合类型(如,元组,字典,集合等),和列表基本相同。
from copy import deepcopy dic = {"C":[1,1,1],"Java":[2,2,2],"Python":[4,4,4],"CJavaPy":[5,5,5]} d1 = deepcopy(dic) #深拷贝 print("d1=",d1) d2 = dic.copy() #浅拷贝 print("d2=",d2) print("--------深拷贝修改子对象--------") #对字典内部子对象列表修改 d1["C"].append(111) d1["CJavaPy"].append(111) print("子对象修改后d1:\n ",d1) print("深拷贝的父对象:\n ",dic) #父对象没有修改 print("--------浅拷贝修改子对象--------") d2["C"].append(222) d2["CJavaPy"].append(222) print("子对象修改后d2:\n ",d2) print("浅拷贝的父对象:\n ",dic) #父对象被修改了
2)字典内部子对象是类对象
from copy import deepcopy class Person: def __init__(self, fname, lname): self.firstname = fname self.lastname = lname def printname(self): print(self.firstname, self.lastname) dic = {"C":Person("c", "c"),"Java":Person("java", "java"),"Python":Person("python", "python"),"CJavaPy":Person("cjavapy", "cjavapy")} d1 = deepcopy(dic) #深拷贝 print("d1=",d1) d2 = dic.copy() #浅拷贝 print("d2=",d2) print("--------深拷贝修改子对象--------") #对字典内部子对象列表修改 d1["C"].firstname = "深拷贝" d1["CJavaPy"].lastname = "深拷贝" print("子对象修改后d1[\"C\"]:") d1["C"].printname() print("深拷贝的父对象中d1[\"C\"]:") #父对象没有修改 dic["C"].printname() print("子对象修改后d1[\"CJavaPy\"]:") d1["CJavaPy"].printname() print("深拷贝的父对象中d1[\"CJavaPy\"]:") #父对象没有修改 dic["CJavaPy"].printname() print("--------浅拷贝修改子对象--------") d2["C"].firstname = "浅拷贝" d2["CJavaPy"].lastname = "浅拷贝" print("子对象修改后d2[\"C\"]:") d2["C"].printname() print("深拷贝的父对象中d2[\"C\"]:")# dic["C"].printname() #父对象被修改了 print("子对象修改后d2[\"CJavaPy\"]:") d2["CJavaPy"].printname() print("深拷贝的父对象中d2[\"CJavaPy\"]:")# dic["CJavaPy"].printname() #父对象被修改了