淺拷貝
淺拷貝僅僅復(fù)制了容器中元素的地址
>>> a=['hello',[1,2,3]]
>>> b=a[:]
>>> [id(x) for x in a]
[55792504, 6444104]
>>> [id(x) for x in b]
[55792504, 6444104]
>>> a[0]='world'
>>> a[1].append(4)
>>> print(a)
['world', [1, 2, 3, 4]]
>>> print(b)
['hello', [1, 2, 3, 4]]
這里可以看出九串,未修改前绞佩,a和b中元素的地址都是相同的,不可變的hello
和可變的list地址都一樣猪钮,說明淺拷貝知識將容器內(nèi)的元素的地址復(fù)制了一份品山。這可以通過修改后,b中字符串沒改變烤低,但是list元素隨著a相應(yīng)改變得到驗證肘交。
淺拷貝是在另一塊地址中創(chuàng)建一個新的變量或容器,但是容器內(nèi)的元素的地址均是源對象的元素的地址的拷貝扑馁。也就是說新的容器中指向了舊的元素( 新瓶裝舊酒 )涯呻。
深拷貝
深拷貝,完全拷貝了一個副本腻要,容器內(nèi)部元素地址都不一樣
>>> from copy import deepcopy
>>> a=['hello',[1,2,3]]
>>> b=deepcopy(a)
>>> [id(x) for x in a]
[55792504, 55645000]
>>> [id(x) for x in b]
[55792504, 58338824]
>>> a[0]='world'
>>> a[1].append(4)
>>>
>>> print(a)
['world', [1, 2, 3, 4]]
>>> print(b)
['hello', [1, 2, 3]]
這里可以看出复罐,深拷貝后,a和b的地址以及a和b中的元素地址均不同雄家,這是完全拷貝的一個副本效诅,修改a后,發(fā)現(xiàn)b沒有發(fā)生任何改變,因為b是一個完全的副本乱投,元素地址與a均不同咽笼,a修改不影響b。
深拷貝是在另一塊地址中創(chuàng)建一個新的變量或容器戚炫,同時容器內(nèi)的元素的地址也是新開辟的剑刑,僅僅是值相同而已,是完全的副本双肤。也就是說( 新瓶裝新酒 )施掏。
舊式類和新式類:
?新式類都從object繼承,經(jīng)典類不需要杨伙。
?新式類的MRO(method resolution order 基類搜索順序)算法采用C3算法廣度優(yōu)先搜索其监,而舊式類的MRO算法是采用深度優(yōu)先搜索
?新式類相同父類只執(zhí)行一次構(gòu)造函數(shù),經(jīng)典類重復(fù)執(zhí)行多次限匣。
其中:
?截止到python2.1抖苦,只存在舊式類。舊式類中米死,類名和type是無關(guān)的:如果x是一個舊式類锌历,那么x.class定義了x的類名,但是type(x)總是返回<type 'instance'>峦筒。這反映了所有的舊式類的實例是通過一個單一的叫做instance的內(nèi)建類型來實現(xiàn)的究西,這是它和類不同的地方。
?新式類是在python2.2為了統(tǒng)一類和實例引入的物喷。一個新式類只能由用戶自定義卤材。如果x是一個新式類的實例,那么type(x)和x.class是一樣的結(jié)果(盡管這不能得到保證峦失,因為新式類的實例的class方法是允許被用戶覆蓋的)扇丛。
?Python 2.x中默認(rèn)都是經(jīng)典類,只有顯式繼承了object才是新式類
?Python 3.x中默認(rèn)都是新式類,經(jīng)典類被移除尉辑,不必顯式的繼承object
Python2.x中:
1. class A:
2. pass
3. class B:
4. pass
5. class C(B):
6. pass
7. class D(C,A):
8. pass
執(zhí)行順序為:D->C->B,->A
python3:
1. class A(object):
2. pass
3. class B(object):
4. pass
5. class C(object):
6. pass
7. class D(A,B,C):
8. pass
執(zhí)行順序為: D->A->B->C->Object