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() #父对象被修改了