在python中,对象赋值实际上是对象的引用。也就是说,当你创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用。
1.浅拷贝
假设创建一个person对象,拷贝两个对象:假设是一对夫妻,hubby和wifey
一种是切片方法,一种是工厂方法
拷贝后,分别给hubby和wifey的name赋值;
当hubby取走50后,影响到wifey的saving。(如果说夫妻共用一个账户,则这种方法是可行的;假如夫妻二人是单独账户,则这种方式不可行)
#encoding=utf-8 person=['name',['saving',100]] #切片方法 hubby=person[:] #工厂方法 wifey=list(person) print [id(x) for x in person,hubby,wifey] #更改前,hubby和wifey的id print [id(x) for x in hubby] print [id(x) for x in wifey] hubby[0]='Joe' wifey[0]='Jane' print hubby,wifey #更改后,hubby和wifey的id print [id(x) for x in hubby] print [id(x) for x in wifey] #将hubby的saving的值改为50 hubby[1][1]=50 print hubby,wifey
输出:
[56231112L, 56232520L, 54732744L] [54219640L, 56127816L] [54219640L, 56127816L] ['Joe', ['saving', 100]] ['Jane', ['saving', 100]] [56306784L, 56127816L] [56306824L, 56127816L] ['Joe', ['saving', 50]] ['Jane', ['saving', 50]]
图例分析:
原因解释:以上操作只是做个一次浅拷贝。
浅拷贝:拷贝的对象本身是新的,但是内容不是。也就是说在另一块地址中创建一个新的变量 或容器,但是容器内的元素的地址均是源对象的元素的地址的拷贝。
2深拷贝
接着上面的案例,如果夫妻二人分开账户,这就需要深拷贝技术——copy.deepcopy()
深拷贝:拷贝的对象是新的,内容也是新的。
#encoding=utf-8 import copy person=['name',['saving',100]] hubby=person #深拷贝 wifey=copy.deepcopy(person) print [id(x) for x in person,hubby,wifey] hubby[0]='Joe' wifey[0]='Jane' print hubby,wifey hubby[1][1]=50 print hubby,wifey print [id(x) for x in hubby] print [id(x) for x in wifey]输出:
[56034696L, 56034696L, 56051144L] ['Joe', ['saving', 100]] ['Jane', ['saving', 100]] ['Joe', ['saving', 50]] ['Jane', ['saving', 100]] [56100704L, 56035912L] [56100744L, 56051080L]深拷贝后,可以看到两个id都不相同了。