摘要:沒(méi)想到會(huì)被轉(zhuǎn)發(fā)??磥?lái)眼球多了的確容易糾錯(cuò)。有時(shí)候你已經(jīng)用它寫了數(shù)萬(wàn)行代碼,自以為很熟了。賦值最簡(jiǎn)單的賦值到底發(fā)生了什么呢一個(gè)變量被賦值了太籠統(tǒng)了吧。也就是說(shuō)是把同一個(gè)對(duì)象傳給了。這里,所綁定的對(duì)象的確被傳進(jìn)來(lái)了,的確生成了一個(gè)新對(duì)象。
[EDIT] 沒(méi)想到會(huì)被轉(zhuǎn)發(fā)。很高興也很囧??磥?lái)眼球多了的確容易糾錯(cuò)。要小心啊小心。
編程語(yǔ)言就是這樣。有時(shí)候你已經(jīng)用它寫了數(shù)萬(wàn)行代碼,自以為很熟了。知道某一天遇到一個(gè)意料之外的問(wèn)題。然后你才發(fā)現(xiàn),原來(lái)TMD是這樣的。
問(wèn)題def change(l1, l2): l1.append(10) l2 = [7, 5, 3, 1] list1 = [1, 3, 5, 7] list2 = [3, 3, 3, 3] change(list1, list2) print(list1) print(list2)
以上這段代碼的輸出是什么?如果你的答案是
[1, 3, 5, 7, 10] [3, 3, 3, 3]
那么大牛請(qǐng)安靜的離開(kāi)。如果不是,可以讀一下下面的故事。
賦值最簡(jiǎn)單的賦值
list1 = [1, 3, 5, 7]
到底發(fā)生了什么呢?一個(gè)變量list1被賦值了?太籠統(tǒng)了吧。
對(duì)于Python來(lái)說(shuō),Everything is an object。上面這行代碼其實(shí)是這樣的:
創(chuàng)建一個(gè)list對(duì)象
創(chuàng)建一個(gè)名字
綁定
再來(lái)看個(gè)例子:
s1 = "hello" s2 = "hello" print(s1 is s2)
這個(gè)會(huì)輸出什么?True! 因?yàn)槭沁@樣的:
創(chuàng)建一個(gè)string對(duì)象
創(chuàng)建名字s1并綁定到string對(duì)象
創(chuàng)建名字s2并綁定到string對(duì)象
而s1和s2綁定的是同一個(gè)對(duì)象!
漲姿勢(shì)了。那么問(wèn)題又來(lái)了:
l1 = [1, 3, 5, 7] l2 = [1, 3, 5, 7] print(l1 is l2)
結(jié)果是?。。。。。。一定是True了吧?錯(cuò)!
這里又有一個(gè)很重要的概念。Mutable 和 immutable。"hello"和[1, 3, 5, 7]的區(qū)別就在于:前者是Immutable而后者是Mutable。對(duì)于可變的對(duì)象,Python會(huì)自動(dòng)生成全新的對(duì)象,以確保各對(duì)象可以獨(dú)立的變動(dòng)。而不可變的就不需要 - 節(jié)省內(nèi)存。
傳參回到開(kāi)始的問(wèn)題。當(dāng)list1被傳給change()的時(shí)候,到底是什么被傳過(guò)去了?讓我們來(lái)做一個(gè)小實(shí)驗(yàn)。在傳入前和change()內(nèi)部各加入一個(gè)語(yǔ)句
print(id(list1))
和
print(id(l1))
這里要解釋一下,Python的每一個(gè)對(duì)象都有一個(gè)唯一的hash id。id()這個(gè)函數(shù)就是用來(lái)打印出這個(gè)id的。加了上面兩行之后,我們會(huì)發(fā)現(xiàn)。在change()函數(shù)之外與之內(nèi),兩個(gè)值是一樣的。也就是說(shuō)Python是把同一個(gè)對(duì)象傳給了change()。
這下我們就可以理解為什么list1在調(diào)用了change()之后被改動(dòng)了。但是那么list2也應(yīng)該被改動(dòng)了才對(duì)???非也。這里,list2所綁定的對(duì)象的確被傳進(jìn)來(lái)了,的確生成了一個(gè)新list對(duì)象。但是這個(gè)對(duì)象被綁定給了l2。跟list2沒(méi)半毛錢關(guān)系。我們?cè)谧鲆粋€(gè)實(shí)驗(yàn)驗(yàn)證一下。
def change(l1, l2): l1.append(10) l2 = [7, 5, 3, 1] list1 = [1, 3, 5, 7] list2 = [3, 3, 3, 3] change(list1, list2) print(list1) print(list2) import dis dis.dis(change)
對(duì)比開(kāi)始的代碼,我們加入了最后兩句。這個(gè)兩句使用了dis模塊把change反編譯了。結(jié)果如下:
2 0 LOAD_FAST 0 (l1)
3 LOAD_ATTR 0 (append) 6 LOAD_CONST 1 (10) 9 CALL_FUNCTION 1 12 POP_TOP
3 13 LOAD_CONST 2 (7)
16 LOAD_CONST 3 (5) 19 LOAD_CONST 4 (3) 22 LOAD_CONST 5 (1) 25 BUILD_LIST 4 28 STORE_FAST 1 (l2) 31 LOAD_CONST 0 (None) 34 RETURN_VALUE
對(duì)應(yīng)原來(lái)的行號(hào)3,我們可以看到,Python用4個(gè)常數(shù)build了一個(gè)list。然后把這個(gè)綁定到了名字l2然后就返回了。
至此真相大白。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/38150.html
摘要:返回元組中元素最大值。將列表轉(zhuǎn)換為元組。如果相對(duì)元組排序,通常先得將它轉(zhuǎn)換為列表并使其成為一個(gè)可變對(duì)象,才能獲得使用排序方法,或使用內(nèi)置方法。 比List更安全的數(shù)據(jù)類型 大家好,今天為大家介紹一種更為安全的Python內(nèi)置數(shù)據(jù)類型:tuple(元組),以及它的基礎(chǔ)用法 元組是什么 元組(tuple)是另一種有序的數(shù)據(jù)類型,與list比較類似。主要不同的一點(diǎn)是tuple被創(chuàng)建后就不能對(duì)...
摘要:所謂金三銀四金九銀十說(shuō)的就是招聘季。大家想過(guò)沒(méi)有,為什么是金三銀四金九銀十就連蘋果輸入法也知道這事情因?yàn)楝F(xiàn)在大多數(shù)的大學(xué)寒假都是放到月份前后,暑假是在月份前后。 今天終于有時(shí)間好好給大家寫寫關(guān)于如何寫簡(jiǎn)歷,給自己加分了。 這篇文章拖了很久了應(yīng)該說(shuō),本來(lái)想在上周寫的,但是事情實(shí)在是太多,又不想草草了事,所以擱置到現(xiàn)在。今天早上正好空出來(lái)了,就馬上給大家碼出來(lái)了。 showImg(http...
摘要:判斷奇數(shù)是迭代器會(huì)根據(jù)提供的函數(shù)對(duì)指定序列做映射語(yǔ)法可以對(duì)可迭代對(duì)象中的每一個(gè)元素進(jìn)行映射。 python內(nèi)置庫(kù)詳解 1、引言2、內(nèi)置庫(kù)詳解2.1 數(shù)據(jù)相關(guān)2.1...
摘要:前端準(zhǔn)備前端了解過(guò)關(guān)了嗎前端基礎(chǔ)架構(gòu)和硬核介紹技術(shù)棧的選擇首先我們構(gòu)建前端架構(gòu)需要對(duì)前端生態(tài)圈有一切了解,并且最好帶有一定的技術(shù)前瞻性,好的技術(shù)架構(gòu)可能日后會(huì)方便的擴(kuò)展,減少重構(gòu)的次數(shù),即使重構(gòu)也不需要大動(dòng)干戈,我通常選型技術(shù)棧會(huì)參考以下三 # 前端準(zhǔn)備 :前端了解過(guò)關(guān)了嗎?前端基礎(chǔ)架構(gòu)和硬核介紹 showImg(https://segmentfault.com/img/remote/...
閱讀 3745·2021-11-16 11:41
閱讀 2956·2021-09-23 11:45
閱讀 746·2019-08-30 15:44
閱讀 630·2019-08-30 13:10
閱讀 2008·2019-08-30 12:49
閱讀 3590·2019-08-28 17:51
閱讀 1559·2019-08-26 12:20
閱讀 761·2019-08-23 17:56