您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)python里面拷貝一個(gè)對(duì)象的方法的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考。一起跟隨小編過來看看吧。
Python中的對(duì)象之間賦值時(shí)是按引用傳遞的,如果需要拷貝對(duì)象,需要使用標(biāo)準(zhǔn)庫中的
copy模塊
1.copy.copy 淺拷貝 只拷貝父對(duì)象,不會(huì)拷貝對(duì)象的內(nèi)部的子對(duì)象。 2. copy.deepcopy 深拷貝 拷貝對(duì)象及其子對(duì)象
一、http://blog.csdn.net/sharkw/article/details/1934090
需求:
你想復(fù)制一個(gè)對(duì)象.因?yàn)樵赑ython中,無論你把對(duì)象做為參數(shù)傳遞,做為函數(shù)返回值,都是引用傳遞的.
討論:
標(biāo)準(zhǔn)庫中的copy模塊提供了兩個(gè)方法來實(shí)現(xiàn)拷貝.一個(gè)方法是copy,它返回和參數(shù)包含內(nèi)容一樣的對(duì)象.
import copy new_list = copy.copy(existing_list)
有些時(shí)候,你希望對(duì)象中的屬性也被復(fù)制,可以使用deepcopy方法:
import copy new_list_of_dicts = copy.deepcopy(existing_list_of_dicts)
當(dāng)你對(duì)一個(gè)對(duì)象賦值的時(shí)候(做為參數(shù)傳遞,或者做為返回值),Python和Java一樣,總是傳遞原始對(duì)象的引用,而不是一個(gè)副本.其它一些語言當(dāng)賦值的時(shí)候總是傳遞副本.Python從不猜測(cè)用戶的需求 ,如果你想要一個(gè)副本,你必須顯式的要求.
Python的行為很簡(jiǎn)單,迅速,而且一致.然而,如果你需要一個(gè)對(duì)象拷貝而并沒有顯式的寫出來,會(huì)出現(xiàn)問題的,比如:
>>> a = [1, 2, 3] >>> b = a >>> b.append(5) >>> print a, b [1, 2, 3, 5] [1, 2, 3, 5]
在這里,變量a和b都指向同一個(gè)對(duì)象(一個(gè)列表),所以,一旦你修改了二者之一,另外一個(gè)也會(huì)受到影響.無論怎樣,都會(huì)修改原來的對(duì)象.
注意:
要想成為一個(gè)Python高手,首先要注意的問題就是對(duì)象的變更操作和賦值,它們都是針對(duì)對(duì)象的引用操作的.一個(gè)語句比如a = []將a重新綁定給一個(gè)新對(duì)象,但不會(huì)影響以前的對(duì)象.然而,對(duì)象復(fù)制卻不同,當(dāng)對(duì)象復(fù)制后,對(duì)象變更操作就有了區(qū)別.
如 果你想修改一個(gè)對(duì)象,而且想讓原始的對(duì)象不受影響,那你就需要對(duì)象復(fù)制.正如本節(jié)說的一樣,你可以使用copy模塊中的兩個(gè)方法來實(shí)現(xiàn)需求.一般的,可以 使用copy.copy,它可以進(jìn)行對(duì)象的淺復(fù)制(shallow copy),它復(fù)制了對(duì)象,但對(duì)于對(duì)象中的元素,依然使用引用.
淺復(fù)制,有時(shí)無法獲得一個(gè)和原來對(duì)象完全一致的副本,如果你想修改對(duì)象中的元素,不僅僅是對(duì)象本身的話:
>>> list_of_lists = [ ['a'], [1, 2], ['z', 23] ] >>> copy_lol = copy.copy(lists_of_lists) >>> copy_lol[1].append('boo') >>> print list_of_lists, copy_lol [['a'], [1, 2, 'boo'], ['z', 23]] [['a'], [1, 2, 'boo'], ['z', 23]]
在這里,變量list_of_lists,copy_lol指向了兩個(gè)不同的對(duì)象,所以我們可以修改它們?nèi)魏我粋€(gè), 而不影響另外一個(gè).然而,如果我們修改了一個(gè)對(duì)象中的元素,那么另一個(gè)也會(huì)受影響,因?yàn)樗鼈冎械脑剡€是共享引用.
如果你希望復(fù)制一個(gè)容器對(duì)象,以及它里面的所有元素(包含元素的子元素),使用copy.deepcopy,這個(gè)方法會(huì)消耗一些時(shí)間和空間,不過,如果你需要完全復(fù)制,這是唯一的方法.
對(duì)于一般的淺拷貝,使用copy.copy就可以了,當(dāng)然,你需要了解你要拷貝的對(duì)象.要復(fù)制列表L,使用list(L),要復(fù)制一個(gè)字典d,使用dict(d),要復(fù)制一個(gè)集合s,使用set(s),這樣,我們總結(jié)出一個(gè)規(guī)律,如果你要復(fù)制一個(gè)對(duì)象o,它屬于內(nèi)建的類型t,那么你可以使用t(o)來 獲得一個(gè)拷貝.dict也提供了一個(gè)復(fù)制版本,dict.copy,這個(gè)和dict(d)是一樣,我推薦你使用后者,這個(gè)使得代碼更一致,而且還少幾個(gè)字符.
要復(fù)制一個(gè)別的類型,無論是你自己寫的還是使用庫中的,使用copy.copy,如果你自己寫一個(gè)類,沒有必要費(fèi)神去寫clone和copy函數(shù),如果你想定義自己的類復(fù)制的方式,實(shí)現(xiàn)一個(gè)__copy__,或者_(dá)_getstate__和__setstate__.如果你想定義自己類型的deepcopy,實(shí)現(xiàn)方法__deepcopy__.
注意你不用復(fù)制不可修改對(duì)象(string,數(shù)字,元組),因?yàn)槟悴挥脫?dān)心修改它們.如果你想嘗試一下復(fù)制,依然會(huì)得到原來的.雖然無傷大雅,不過真的浪費(fèi)盡力:
>>> s = 'cat' >>> t = copy.copy(s) >>> s is t True
is操作符用于不僅判斷兩個(gè)對(duì)象是否完全一致,而且是同一個(gè)對(duì)象(is判斷標(biāo)識(shí)符,要比較內(nèi)容,使用==),判斷標(biāo)識(shí)符是否相等對(duì)于不可修改對(duì)象沒有什么意義.然而 ,判斷標(biāo)識(shí)符對(duì)于可修改對(duì)象有時(shí)候是很重要的,比如,你不確定a和b是否指向同一個(gè)對(duì)象,使用a is b會(huì)立刻得到結(jié)果.這樣你可以自己判斷是否需要使用對(duì)象拷貝.
注意:
你可以使用另一種拷貝方式,給定一個(gè)列表L,無論是完整切片L[:]或者列表解析[x for x in L],都會(huì)獲得L的淺拷貝,試試L+[],L*1...但是上面兩種方法都會(huì)使人迷惑,使用list(L)最清晰和快速,當(dāng)然,由于歷史原因,你可能會(huì)經(jīng)??吹絃[:]的寫法.
對(duì)于dict,你可能見過下面的復(fù)制方法:
>>> for somekey in d: ... d1[somekey] = d[somekey]
或者更簡(jiǎn)單一些的方法,d1={},d1.update(d),無論怎樣,這些代碼都是缺乏效率的,使用d1=dict(d)吧.
相關(guān)說明:
copy(x) Shallow copy operation on arbitrary Python objects. See the module's __doc__ string for more info. deepcopy(x, memo=None, _nil=[]) Deep copy operation on arbitrary Python objects. See the module's __doc__ string for more info.
感謝各位的閱讀!關(guān)于python里面拷貝一個(gè)對(duì)象的方法就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。