常見的 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
>>> 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。除非正確處理這個地方,否則很容易出問題。