避坑指南!Python里面的這九個坑,坑的就是你!
Python里面有一些坑,讓你防不勝防,菜鳥經(jīng)常會弄暈,而學(xué)習(xí)多年的Python老鳥也會時不時中招。小編整理了9個坑,都是會經(jīng)常碰到的坑,讓你大呼我曾經(jīng)也碰到過!
雖然是小的問題,但是在實(shí)際的項(xiàng)目中,哪怕一個很小的錯誤,都會引起一連串的問題。有的時候,為了找這一個微小的bug要花費(fèi)很大的力氣,讓人很郁悶。
坑1.lambda自由參數(shù)之坑
排序和分組的key函數(shù)常使用lambda,表達(dá)更加簡潔,但是有個坑新手容易掉進(jìn)去:
但是實(shí)際卻輸出: 3,3,3. 定義lambda使用的i被稱為自由參數(shù),它只在調(diào)用lambda函數(shù)時,值才被真正確定下來,這就猶如下面打印出2,你肯定確信無疑吧。
正確做法是轉(zhuǎn)化自由參數(shù)為lambda函數(shù)的默認(rèn)參數(shù),就是給i一個默認(rèn)的值:
坑2. 默認(rèn)參數(shù)設(shè)置為空
含有默認(rèn)參數(shù)的函數(shù),如果類型為容器,且設(shè)置為空:
這是可變類型的默認(rèn)參數(shù)之坑,請務(wù)必設(shè)置此類默認(rèn)參數(shù)為None:
坑3.共享變量未綁定之坑
有時想要多個函數(shù)共享一個全局變量,但卻在某個函數(shù)內(nèi)試圖修改它為局部變量:
應(yīng)該在f函數(shù)內(nèi)顯示聲明i為global變量:
坑4.各種參數(shù)使用之坑
4.1) 位置參數(shù)必須一一對應(yīng),缺一不可
但是下面這樣的調(diào)用就不ok:
4.2) 關(guān)鍵字參數(shù)必須在位置參數(shù)右邊
這樣就是不行,關(guān)鍵字參數(shù)必須在位置參數(shù)的右邊
4.3) 可變關(guān)鍵字參數(shù)
如下x是可變關(guān)鍵字參數(shù):
但是不能這樣玩:
- f(1) TypeError: f() takes 0 positional arguments but 1 was given
坑5 列表刪除之坑
刪除一個列表中的元素,此元素可能在列表中重復(fù)多次:
考慮刪除這個序列[1,5,5,5,7]中的元素5,結(jié)果發(fā)現(xiàn)只刪除其中兩個:[1, 5, 7]
原因是這個序列在刪除的時候,動態(tài)的縮短,當(dāng)你第二次循環(huán)的時候,已經(jīng)跳過了一個5。
正確的做法,構(gòu)造成字典:
利用字典的key的唯一性,這樣就能很干凈的刪除了。
坑6.相同值的不可變對象
key=1,value=go的鍵值對神奇消失了,這個是什么原因,有點(diǎn)丈二和尚摸不著頭腦。這是因?yàn)榫哂邢嗤档牟豢勺儗ο笤赑ython中始終具有相同的哈希值。由于存在哈希沖突,不同值的對象也可能具有相同的哈希值。
坑7.謎一樣的字符串駐留
如果上面例子返回True,但是下面例子我們稍微換一下,加入一個@為什么是False:

這與Cpython 編譯優(yōu)化相關(guān),行為稱為字符串駐留,但駐留的字符串中只包含字母,數(shù)字或下劃線。
坑8.奇怪的for
是不是很奇怪,執(zhí)行了一次for循環(huán)之后,i就變成了5,為什么不是執(zhí)行一次就退出?其實(shí)for在Python中的工作方式是這樣的,range(5)生成的下一個元素就被解包,并賦值給目標(biāo)列表的變量i,所以 i = 5 并不會影響循環(huán)。
坑9.生成器的執(zhí)行時機(jī)
g為生成器,list(g)后返回[2,4,6],因?yàn)槊總€元素肯定至少都出現(xiàn)一次。所以這個結(jié)果這不足為奇。但是,請看下例:
這是不是有點(diǎn)不可思議~~ 原因在于,生成器表達(dá)式中, in 子句在聲明時執(zhí)行, 而條件子句則是在運(yùn)行時執(zhí)行。
或者我們這樣解釋就明白了:
618來襲,雖然Python的電子書很多,但是經(jīng)典的Python書籍還是要看紙質(zhì)的書,感覺這樣才有踏實(shí)感,而且長時間眼睛閱讀也會舒服一些。