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