Python開(kāi)發(fā)中常見(jiàn)的10個(gè)陷阱你踩過(guò)幾個(gè)(附解決方案)
作為一門(mén)簡(jiǎn)潔優(yōu)雅的語(yǔ)言,Python深受開(kāi)發(fā)者喜愛(ài)。然而,即使是經(jīng)驗(yàn)豐富的Python開(kāi)發(fā)者,也難免會(huì)遇到一些"坑"。本文將介紹Python中10個(gè)最常見(jiàn)的陷阱,幫助大家避免這些錯(cuò)誤,寫(xiě)出更健壯的代碼。
1. 可變默認(rèn)參數(shù)
def append_to(element, to=[]): to.append(element) return to print(append_to(1)) # 輸出: [1] print(append_to(2)) # 輸出: [1, 2] 而不是預(yù)期的[2]
問(wèn)題原因:默認(rèn)參數(shù)在函數(shù)定義時(shí)就被創(chuàng)建,而不是每次調(diào)用時(shí)創(chuàng)建。
解決方案:
def append_to(element, to=None): if to is None: to = [] to.append(element) return to
2. 循環(huán)中修改列表
lst = [1, 2, 3, 4] for item in lst: if item % 2 == 0: lst.remove(item) print(lst) # 輸出: [1, 3] 而不是預(yù)期的[1, 3]
看似正確,但如果列表連續(xù)有兩個(gè)偶數(shù)元素,會(huì)出問(wèn)題:
lst = [1, 2, 4, 5] for item in lst: if item % 2 == 0: lst.remove(item) print(lst) # 輸出: [1, 4, 5] 因?yàn)閯h除2后,4的索引變成了1被跳過(guò)了
解決方案:使用列表推導(dǎo)式或創(chuàng)建副本
lst = [x for x in lst if x % 2 != 0] # 或 for item in lst[:]: if item % 2 == 0: lst.remove(item)
3. 閉包變量綁定
funcs = [] for i in range(3): def func(): return i funcs.append(func) print([f() for f in funcs]) # 輸出: [2, 2, 2] 而不是預(yù)期的[0, 1, 2]
問(wèn)題原因:閉包中的變量是延遲綁定的。
解決方案:使用默認(rèn)參數(shù)或functools.partial
for i in range(3): def func(i=i): return i funcs.append(func)
4. == 和 is 的區(qū)別
a = [1, 2, 3] b = a c = [1, 2, 3] print(a == b) # True print(a is b) # True print(a == c) # True print(a is c) # False
解釋?zhuān)?=比較值,is比較對(duì)象標(biāo)識(shí)(內(nèi)存地址)。
5. 整數(shù)緩存問(wèn)題
a = 256 b = 256 print(a is b) # True a = 257 b = 257 print(a is b) # False (在交互式環(huán)境中)
解釋?zhuān)篜ython會(huì)緩存小整數(shù)(-5到256),大整數(shù)每次創(chuàng)建新對(duì)象。
6. 類(lèi)變量和實(shí)例變量
class A: x = 1 class B(A): pass class C(A): pass B.x = 2 print(A.x, B.x, C.x) # 輸出: 1 2 1 A.x = 3 print(A.x, B.x, C.x) # 輸出: 3 2 3
解釋?zhuān)侯?lèi)變量在繼承時(shí)會(huì)被共享,除非子類(lèi)顯式覆蓋。
7. 字符串駐留
a = "hello" b = "hello" print(a is b) # True a = "hello world" b = "hello world" print(a is b) # False (取決于實(shí)現(xiàn))
解釋?zhuān)篜ython會(huì)對(duì)短字符串進(jìn)行駐留優(yōu)化,但不要依賴(lài)這種行為。
8. 生成器只能遍歷一次
gen = (x for x in range(3)) print(list(gen)) # [0, 1, 2] print(list(gen)) # [] 因?yàn)樯善饕押谋M
解決方案:如果需要多次使用,可以轉(zhuǎn)換為列表或重新創(chuàng)建生成器。
9. 淺拷貝與深拷貝
lst = [1, [2, 3]] lst2 = lst.copy() lst2[1][0] = 4 print(lst) # [1, [4, 3]] 原始列表也被修改了
解決方案:需要深拷貝時(shí)使用copy.deepcopy
import copy lst2 = copy.deepcopy(lst)
10. try-except中的return
def func(): try: return 1 finally: return 2 print(func()) # 輸出: 2
解釋?zhuān)篺inally中的return會(huì)覆蓋try中的return。
到此這篇關(guān)于Python開(kāi)發(fā)中常見(jiàn)的10個(gè)陷阱你踩過(guò)幾個(gè)(附解決方案)的文章就介紹到這了,更多相關(guān)Python開(kāi)發(fā)常見(jiàn)陷阱內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python常見(jiàn)統(tǒng)計(jì)分析處理函數(shù)解讀
這篇文章主要介紹了python常見(jiàn)統(tǒng)計(jì)分析處理函數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07對(duì)python cv2批量灰度圖片并保存的實(shí)例講解
今天小編就為大家分享一篇對(duì)python cv2批量灰度圖片并保存的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-11-11Pytorch卷積神經(jīng)網(wǎng)絡(luò)resent網(wǎng)絡(luò)實(shí)踐
這篇文章主要為大家介紹了Pytorch卷積神經(jīng)網(wǎng)絡(luò)resent網(wǎng)絡(luò)實(shí)踐,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Python深度學(xué)習(xí)實(shí)戰(zhàn)PyQt5基本控件使用解析
PyQt5 提供了豐富的輸入輸出控件。本文介紹通過(guò) QtDesigner 工具欄創(chuàng)建常用的基本控件,包括各種按鈕控件、文本輸入控件和調(diào)節(jié)輸入控件2021-10-10Android應(yīng)用開(kāi)發(fā)中Action bar編寫(xiě)的入門(mén)教程
這篇文章主要介紹了Android應(yīng)用開(kāi)發(fā)中ActionBar編寫(xiě)的入門(mén)教程,Action Bar可以實(shí)現(xiàn)的功能很多,比如導(dǎo)航菜單和標(biāo)簽頁(yè)切換等,需要的朋友可以參考下2016-02-02在python win系統(tǒng)下 打開(kāi)TXT文件的實(shí)例
下面小編就為大家分享一篇在python win系統(tǒng)下 打開(kāi)TXT文件的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04conda將python低版本環(huán)境升級(jí)到高版本的完整步驟
這篇文章主要給大家介紹了關(guān)于conda將python低版本環(huán)境升級(jí)到高版本的完整步驟,包括激活環(huán)境、升級(jí)Python版本、驗(yàn)證升級(jí)、處理依賴(lài)問(wèn)題和測(cè)試環(huán)境等步驟,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-04-04一起來(lái)學(xué)習(xí)Python的元組和列表
這篇文章主要為大家詳細(xì)介紹了Python元組和列表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03