致命錯誤!Python開發者的7個崩潰瞬間

毫無疑問,Python是當今使用最爲普遍的編程語言。它的語法簡單且易讀,也很容易上手。python

但不管你經驗多豐富,或是已使用過多少種語言,切換到Python時都不能保證很是順利。具備面向對象編程背景的開發人員容易忽略Python的慣用特性,極可能會濫用編程結構,從而產生不可預見且很難捕捉的錯誤。更糟糕的是,大多數錯誤很難發現,可能在後續工做中形成麻煩。程序員

不少人學習python,不知道從何學起。web

不少人學習python,掌握了基本語法事後,不知道在哪裏尋找案例上手。編程

不少已經作案例的人,殊不知道如何去學習更加高深的知識。app

那麼針對這三類人,我給你們提供一個好的學習平臺,免費領取視頻教程,電子書籍,以及課程的源代碼!??¤編程語言

QQ羣:1057034340函數

下文彙總了程序員(尤爲是新手)可能犯的常見錯誤,以及該如何糾正這些錯誤,編寫更好的、無錯誤的Python代碼。讓咱們開始吧!學習

編寫過於風格化的代碼ui

這是Python初學者的一個典型特徵。爲了編寫相似高級僞英語的代碼,他們最終在其代碼庫中添加了如下類型的代碼段:spa

if x == 1 or x == 2

看起來彷佛不錯。這行代碼的意思是變量x必須爲1或2才能知足條件。可是,此類代碼片斷太過風格化,影響了可讀性。下面的替代代碼段很容易理解,該行代碼檢查值是否屬於列表中的元素:

if x in [1,2]

沒必要要的比較運算符:None和零

具備Java背景的程序員知道須要進行多少次空值(null)檢查(尤爲是在Java 8以前的版本中)。所以,在Python中看到這樣的比較運算符就不足爲奇了:

a == None b != None

上述狀況能夠利用python的方式編寫代碼來加強可讀性:

a is None

b is not None

一樣值得注意的是,對於0,實際上並不須要在條件邏輯中使用比較運算符。0解釋爲false,而非零數字則視爲true。

使用長鏈式條件位邏輯

在大多數語言(包括Swift,Java,Kotlin)中,可用如下方式編寫某些比較邏輯:

if a < b < c

大多數語言不能在非關聯優先級中使用相鄰運算符,而Python則不一樣,Python能夠鏈式賦值,如如下代碼所示:

if a < b < c

所以,這樣作能夠避免按位運算符。

使用type()代替isinstance(),反之亦然

type和isinstance是Python中用於類型檢查的兩個普遍使用的內置函數。一般,新手開發人員會認爲這兩個函數很類似並互換使用。這可能引起沒法預料的錯誤,由於type()和isinstance()具備一些細微的差別。

isinstance()函數用於檢查對象是不是指定類的實例,同時還要注意繼承。另外一方面,type()僅檢查引用類型是否相等,並丟棄子類型。所以,如下代碼使用type()和isinstance()給出了不一樣的結果:

class Vehicle:

pass

class Car(Vehicle):

passisinstance(Car(), Vehicle) #returns True

type(Car()) == Vehicle # returns False

一樣,如下代碼將布爾值視爲int的實例(由於True和False基本上被視爲1和0),可是使用type函數給出了不一樣的結果。

type(True) == int # falseisinstance(True, int) # trueisinstance(False,int) # true

所以,重要的是要了解Python的兩個類型檢查器函數之間的差別,而且不要彼此混淆。

混淆做用域中的局部變量和全局變量

Python中的做用域規則看起來至關簡單,但很容易形成誤解。例如,如下代碼在函數內部使用全局變量:

a = 10

def printMe():

print(a)printMe() # prints 10

若是經過修改函數中的變量來稍微調整上述代碼,就會拋出錯誤:

a = 20

def printA():

print(a)

a = 10print(a) # gives 20

printA() # gives error as a is referenced before assigned

一旦在函數內部修改了全局變量,Python就會將其視爲局部變量,從而覆蓋全局變量。甚至賦值前的打印語句也沒有執行。

爲確保此類名稱衝突不會致使錯誤,能夠在局部函數內爲全局變量附加global關鍵字。甚至最好將全局變量(若是確實須要使用)放在單獨的類中,以便始終將全局變量與類名一塊兒使用。

可變默認參數

在Python中,使用默認參數很常見,它能夠避免在調用函數時出現一長串參數。列表、字典和集合是Python中的可變類型。設置默認值會致使意外結果,以下所示:

def addToList(x, a=[]):

a.append(x)

return alistOne = addToList(5)

#prints [5]anotherList = addToList(10)

# [5, 10]

如你所見,第二個列表包含先前添加的元素,由於函數中的可變默認參數將它們存儲在各個狀態之間。

Python中可變默認對象的問題表如今定義函數時會對其進行評估,這會致使可變值也保存先前的內容。爲避免此類嚴重的錯誤,請將None設置爲默認值,而後在函數內分配可變變量,以下所示:

def addElement(x, a=None):

if not a:

a = []

a.append(x)

return a

忽略多重繼承和方法解析順序

圖源:unsplash

與大多數語言不一樣,Python支持多重繼承。即在具備繼承的類中,方法和類變量將根據繼承類時指定的順序執行。初學者一般會忽略此概念,尤爲是在僅使用單一繼承的狀況下。在下面的代碼中,當調用C類的方法時,將使用超類B的相應方法:

>>> class A(object):

... def me(self):

print("class A")

>>> class B(A):

... def me(self):

print("class B")

class C(B, A):

passc = C()

c.me() # prints class B

Python中繼承類的順序很重要,它可用來解決這些問題。

Python雖簡單,但當心不要與其餘語言混淆了,這可能會致使奇怪的錯誤和程序崩潰。但願上述的總結能夠幫你理清概念,編寫更穩定的Python代碼。

相關文章
相關標籤/搜索