常見的 Python 編程錯誤

nyyb 9年前發布 | 26K 次閱讀 Python Python開發


這里總結了我多年來進行Python開發所犯的一些錯誤。雖然算不上一個『權威』列表,但這是我發現我的同事和朋友都常犯的錯誤類型。如果你覺得還有其他的錯誤需要補充,請在評論里告訴我!

錯誤 1# 在遍歷的過程中修改列表

Python

>>> li=[1,2,3]

>>> for i in li:

...    i.append(4)
>>>li=[1,2,3]

>>>foriinli:

...    i.append(4)

這個有限循環變成了無限循環

錯誤 2# 錯誤理解了 Python 變量作用域

當一個變量在函數里被賦值時,Python 會假定它是在本函數內部定義的

Python

>>>i=[1,2,3]

>>>def print_i():

…     print i

[1,2,3]

>>>def modify_i():

…     i=i+[4,5]
>>>i=[1,2,3]

>>>defprint_i():

…    printi

[1,2,3]

>>>defmodify_i():

…    i=i+[4,5]

錯誤 3# 認為 True 和 False 是關鍵字

在 Python 2.x 版本中,True 和 False 不是關鍵字,所以

Python

>>>True = False

>>>if True == False:

…     print “end of the world”
>>>True=False

>>>ifTrue==False:

…    print“endoftheworld”

錯誤 4# Python 2.x 和 Python 3.x 之間的差別

在 Python 2.x 中

Python

>>>print “hello world”

hello world
>>>print“helloworld”

hello world

在 Python 3.x 中

Python

>>>print “hello world”

File “<stdin>”, line 1

print “hello”

^

SyntaxError: invalid syntax

>>>print (“hello world”)

hello world
>>>print“helloworld”

File“<stdin>”,line1

print“hello”

^

SyntaxError:invalidsyntax

>>>print(“helloworld”)

hello world

錯誤 5# 數據結構不是不可變對象

Python

>>>li1 = []

>>>li2=li1

>>>li2.append(1)

>>>print li1

[1]
>>>li1=[]

>>>li2=li1

>>>li2.append(1)

>>>printli1

[1]

這是因為我們只創建了一個對象,然后給它綁定了不同的名字。因此當你修改這個對象時,所有指向該對象的變量都會被改變。

錯誤 6# 在異常處理塊中指定了錯誤的參數

Python

>>>try:
…     int(“z”)
>>>except IndexError, ValueError:
…     pass
>>>try:
…    int(“z”)
>>>exceptIndexError,ValueError:
…    pass

這段代碼無法正常運行,因為 IndexError 是你要捕獲的異常類型,ValueError 是指你要把捕獲到的異常賦值給這個變量名

捕獲多種異常的正確代碼應該是這樣:

Python

>>>try:
…     int(“z”)
>>>except (IndexError, ValueError):
…     pass
>>>try:
…    int(“z”)
>>>except(IndexError,ValueError):
…    pass

錯誤 7# is 和 == 操作并不一樣

Python

>>> a=257

>>> b=257

>>> a is b

False

>>> a == b

True

>>> id(a)

23486712

>>> id(b)

23486736
>>>a=257

>>>b=257

>>>aisb

False

>>>a==b

True

>>>id(a)

23486712

>>>id(b)

23486736

is 操作檢查兩個對象是不是同一個對象,而 == 操作檢查兩個對象的值是否相等。

錯誤 8# import 語句只在第一次生效

你可以通過在交互提示符下 import 一個文件來執行它,但在每一次會話中,這個只會生效一次。之后的 import 只是簡單的返回一個已經載入的模塊。想要強制 Python 重新導入并返回一個文件的代碼,可以執行 reload(module)函數。當你想這么做的時候,請確保使用 reload 函數來重新導入,而非再次 import。

錯誤 9# 整數除法

Python

>>> 5/2
2
>>>5/2
2

你可能想要的是:

Python

&gt;&gt;&gt; 5.0/2
2.5
>>>5.0/2
2.5

除法操作至少要有一個操作數是 float 類型。

錯誤 10# 沒有正確理解類變量

Python

>>> class X(object):
…     a = 1
…
>>> class Y(X):
…     pass
…
>>> class Z(X):
…     pass
…
>>> print X.a, Y.a, Z.a
1 1 1
>>>classX(object):
…    a=1
…
>>>classY(X):
…    pass
…
>>>classZ(X):
…    pass
…
>>>printX.a,Y.a,Z.a
111

當 Y 的變量 a 改變時

Python

>>> Y.a = 5
>>> print X.a, Y.a, Z.a
1 5 1
>>>Y.a=5
>>>printX.a,Y.a,Z.a
151

這個結果和我們的預期一樣,但是當我們改變 X 的變量 a 時

Python

>>> X.a = 3
>>> print X.a, Y.a, Z.a
3 5 3
>>>X.a=3
>>>printX.a,Y.a,Z.a
353

和字典一樣,類變量是在內部處理的,并遵循一種 方法解析順序(Method Resolution Order ,MRO)。在上述代碼中,因為在類 Z 中沒有找到該屬性,它會去它的基類(在上例中只有 X,盡管 Python 支持多重繼承)中搜索。換句話說,Z 不像 X,它沒有自己的屬性。因此對 Z.a 的引用實際上指向了 X.a。除非正確處理這個地方,否則很容易出問題。

 本文由用戶 nyyb 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!