python中的賦值是按引用來傳遞的,如果不是賦值而是拷貝,那就需要用到copy模塊了,這就不得不談淺拷貝和深拷貝了。
淺拷貝copy()
- #!/usr/bin/python
- import copy
- class MyClass:
- def __init__(self, name):
- self.name = name
- def __cmp__(self, other):
- return cmp(self.name, other.name)
- a = MyClass('a')
- my_list = [a]
- dup = copy.copy(my_list)
- print ' my_list:', my_list
- print ' dup:', dup
- print ' dup is my_list:', (dup is my_list)
- print ' dup == my_list:', (dup == my_list)
- print 'dup[0] is my_list[0]:', (dup[0] is my_list[0])
- print 'dup[0] == my_list[0]:', (dup[0] == my_list[0])
結果:
my_list: [<__main__.MyClass instance at 0x00BA5530>]
dup: [<__main__.MyClass instance at 0x00BA5530>]
dup is my_list: False
dup == my_list: True
dup[0] is my_list[0]: True
dup[0] == my_list[0]: True
深拷貝deepcopy()
- #!/usr/bin/python
- import copy
- class MyClass:
- def __init__(self, name):
- self.name = name
- def __cmp__(self, other):
- return cmp(self.name, other.name)
- a = MyClass('a')
- my_list = [a]
- dup = copy.deepcopy(my_list)
- print ' my_list:', my_list
- print ' dup:', dup
- print ' dup is my_list:', (dup is my_list)
- print ' dup == my_list:', (dup == my_list)
- print 'dup[0] is my_list[0]:', (dup[0] is my_list[0])
- print 'dup[0] == my_list[0]:', (dup[0] == my_list[0])
結果:
my_list: [<__main__.MyClass instance at 0x00BA5530>]
dup: [<__main__.MyClass instance at 0x00BA5620>]
dup is my_list: False
dup == my_list: True
dup[0] is my_list[0]: False
dup[0] == my_list[0]: True
淺拷貝和深拷貝都是copy,表面好像也看不出什麼區別來。
- import copy
- list1 = ['a','b','c']
- list2 = copy.copy(list1)
- list3 = copy.deepcopy(list1)
- print list1
- print list2
- print list3
結果:
['a', 'b', 'c']
['a', 'b', 'c']
['a', 'b', 'c']
如果只是簡單的拷貝一下沒有後續操作,那麼隨便拷貝都行。淺拷貝和深拷貝都是爲後續操作而區分的。
- import copy
- list1 = ['a','b','c',['d','e']]
- list2 = copy.copy(list1)
- list3 = copy.deepcopy(list1)
- list1.append('f')
- list1[3].append('x')
- print list1
- print list2
- print list3
- list4 = list1
- print list4
結果:
['a', 'b', 'c', ['d', 'e', 'x'], 'f']
['a', 'b', 'c', ['d', 'e', 'x']]
['a', 'b', 'c', ['d', 'e']]
['a', 'b', 'c', ['d', 'e', 'x'], 'f']
從這就能看出來,就以列表爲例,如果淺拷貝,那麼系統就新建一個列表,它的每個元素都指向原來列表的每個元素(就像C語言裏的指針數組),輸出的時候就把它各元素指向的母體元素內容顯示出來,所以list1追加了f元素以後list2並沒有顯示,因爲list2裏並沒有指向這個新元素的元素。但是追加了x以後顯示出來了,因爲x屬於list1的第三個元素的一部分,在list2有對應的指向,所以就顯示出來了。對於深拷貝來說沒有任何改變,因爲深拷貝是新建一個列表,把原列表的內容原封不動拷過來,拷過來以後它和原列表一模一樣,至於原列表後來做了什麼改變根本不關它的事。形象理解就是淺拷貝是活的,深拷貝是死的。