Python開發(fā)中常見的10個(gè)陷阱你踩過幾個(gè)(附解決方案)
作為一門簡潔優(yōu)雅的語言,Python深受開發(fā)者喜愛。然而,即使是經(jīng)驗(yàn)豐富的Python開發(fā)者,也難免會遇到一些"坑"。本文將介紹Python中10個(gè)最常見的陷阱,幫助大家避免這些錯(cuò)誤,寫出更健壯的代碼。
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]
問題原因:默認(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ù)元素,會出問題:
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被跳過了
解決方案:使用列表推導(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]
問題原因:閉包中的變量是延遲綁定的。
解決方案:使用默認(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
解釋:==比較值,is比較對象標(biāo)識(內(nèi)存地址)。
5. 整數(shù)緩存問題
a = 256 b = 256 print(a is b) # True a = 257 b = 257 print(a is b) # False (在交互式環(huán)境中)
解釋:Python會緩存小整數(shù)(-5到256),大整數(shù)每次創(chuàng)建新對象。
6. 類變量和實(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
解釋:類變量在繼承時(shí)會被共享,除非子類顯式覆蓋。
7. 字符串駐留
a = "hello" b = "hello" print(a is b) # True a = "hello world" b = "hello world" print(a is b) # False (取決于實(shí)現(xiàn))
解釋:Python會對短字符串進(jìn)行駐留優(yōu)化,但不要依賴這種行為。
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
解釋:finally中的return會覆蓋try中的return。
到此這篇關(guān)于Python開發(fā)中常見的10個(gè)陷阱你踩過幾個(gè)(附解決方案)的文章就介紹到這了,更多相關(guān)Python開發(fā)常見陷阱內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python遞歸求出列表(包括列表中的子列表)的最大值實(shí)例
今天小編就為大家分享一篇Python遞歸求出列表(包括列表中的子列表)的最大值實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02
Python實(shí)現(xiàn)GIF動(dòng)圖以及視頻卡通化詳解
本文主要介紹了如何使用Python中的animegan2-pytorch實(shí)現(xiàn)動(dòng)圖以及視頻的卡通化效果,文中的代碼具有一定的學(xué)習(xí)價(jià)值,需要的朋友可以參考一下2021-12-12
Python使用schedule庫實(shí)現(xiàn)任務(wù)定時(shí)自動(dòng)化
在Python的自動(dòng)化工具庫中,schedule是一個(gè)簡潔又強(qiáng)大的存在,無論是定時(shí)備份數(shù)據(jù)、周期性抓取網(wǎng)頁,還是定期發(fā)送提醒郵件,schedule庫都能讓我們的代碼按計(jì)劃精準(zhǔn)執(zhí)行,今天我們就深入了解schedule庫的使用,需要的朋友可以參考下2026-04-04
Python GUI編程學(xué)習(xí)筆記之tkinter界面布局顯示詳解
這篇文章主要介紹了Python GUI編程學(xué)習(xí)筆記之tkinter界面布局顯示,結(jié)合實(shí)例形式分析了Python GUI編程中tkinter界面布局顯示的相關(guān)操作技巧與使用注意事項(xiàng),需要的朋友可以參考下2020-03-03
python GUI庫圖形界面開發(fā)之PyQt5窗口控件QWidget詳細(xì)使用方法
這篇文章主要介紹了python GUI庫圖形界面開發(fā)之PyQt5窗口控件QWidget詳細(xì)使用方法,需要的朋友可以參考下2020-02-02
python 獲取當(dāng)天凌晨零點(diǎn)的時(shí)間戳方法
今天小編就為大家分享一篇python 獲取當(dāng)天凌晨零點(diǎn)的時(shí)間戳方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05

