在python中,一切数据皆为对象,分为可变类型(列表,字典)与不可变类型(数字Number,字符串String,元组Tuple)。
针对可变数据类型,对象的赋值指的就是对象的引用,不产生新的对象;浅copy只拷贝父对象,不拷贝父对象的子对象,产生新对象;深copy拷贝整个对象,产生互不影响的完整新对象;新建对象,即便是一模一样的数据,那也是互不影响的新建的对象。
针对不可变数据类型,无所谓赋值、浅copy还是深copy,一个萝卜一个坑,相同的值就是相同的对象,反过来想就是:因为值不可变,那么值相同肯定是同一个对象。
针对不可变数据类型,无所谓对象的引用一说,不同的变量对应同一个对象,这里的变量只是做一个引用计数的统计,对象没人用了就垃圾回收了。
== 表示内容等,内存地址(id)可能不等; is 表示全等,即内存地址(id)和值都相等
l1 = [1, [2, 3], 4] l2 = [1, [2, 3], 4] # 新建对象l2,虽然看起来和l1一样,但其实是新的对象,二者互不影响没有任何关系(开辟新地址) l3 = l1 # 对象的赋值,l3与l1 一模一样(不开辟新地址) l4 = copy.copy(l1) # l4只拷贝l1的父对象,产生新对象,l1父级元素更改不影响l4,子元素更改l4跟着变更(开辟新地址) l5 = copy.deepcopy(l1) # l5彻底拷贝l1,产生互不影响的新对象,l1的任何变更均不影响l5(开辟新地址) print l1 # [1, [2, 3], 4] print l2 # [1, [2, 3], 4] print l3 # [1, [2, 3], 4] print l4 # [1, [2, 3], 4] print l5 # [1, [2, 3], 4] print 'l1-id:', id(l1) # 7664 print 'l2-id:', id(l2) # 6440 print 'l3-id:', id(l3) # 7664 print 'l4-id:', id(l4) # 8168 print 'l5-id:', id(l5) # 7880 print 'l1==l2:', l1 == l2 # true print 'l1==l3:', l1 == l3 # true print 'l1==l4:', l1 == l4 # true print 'l1==l5:', l1 == l5 # true print 'l1 is l2:', l1 is l2 # false print 'l1 is l3:', l1 is l3 # true print 'l1 is l4:', l1 is l4 # false print 'l1 is l5:', l1 is l5 # false print '--------------原始值改变后----------------' l1[1][0] = 0 l1[0] = 0 l4[1][1] = 'a' print l1 # [0, [0, 'a'], 4] print l2 # [1, [2, 3], 4] print l3 # [0, [0, 'a'], 4] print l4 # [1, [0, 'a'], 4] print l5 # [1, [2, 3], 4] print 'l1-id:', id(l1) # 7664 print 'l2-id:', id(l2) # 6440 print 'l3-id:', id(l3) # 7664 print 'l4-id:', id(l4) # 8168 print 'l5-id:', id(l5) # 7880 print 'l1==l2:', l1 == l2 # false print 'l1==l3:', l1 == l3 # true print 'l1==l4:', l1 == l4 # false print 'l1==l5:', l1 == l5 # false print 'l1 is l2:', l1 is l2 # false print 'l1 is l3:', l1 is l3 # true print 'l1 is l4:', l1 is l4 # false print 'l1 is l5:', l1 is l5 # false