N年P(guān)ython老司機(jī),血淚總結(jié)新手常見10大錯誤
作為python的新手,大家在上手python的時候都會或多或少的接觸到一些rookie mistake,也就是菜鳥級別的錯誤。小編作為一個老司機(jī)也是從這些錯誤中一點(diǎn)一點(diǎn)的積累經(jīng)驗(yàn),才慢慢的能夠熟練的使用python。
遇到錯誤不可怕,關(guān)鍵是要學(xué)會如何去避免犯這些錯誤。今天小編就帶領(lǐng)大家看一下作為python新手最常見的幾個錯誤,希望大家能夠在學(xué)習(xí)的過程中,盡量的去避免這些錯誤。
1.默認(rèn)可變對象

上圖中,我們定義了addElement函數(shù),在函數(shù)的形參中,我們默認(rèn)使用了可變對象list。當(dāng)我們連續(xù)的使用默認(rèn)參數(shù)調(diào)用addElement函數(shù)時,可以發(fā)現(xiàn)list1只被創(chuàng)建了一次。由于list屬于python中的可變對象,因此只在函數(shù)被定義的時候才能被創(chuàng)建一次,所以在調(diào)用的時候都使用的創(chuàng)建好的同一個list列表。而對于不可變對象,情況就不同了,如下圖所示。

對于不可變對象,程序在調(diào)用函數(shù)時,將不可變對象作為默認(rèn)參數(shù)進(jìn)行調(diào)用。那么我們?nèi)绾谓鉀Q這個問題呢,我們可以利用不可變對象進(jìn)行判斷解決,程序如下圖所示。
我們利用條件判斷,list1是否為None,來決定是否創(chuàng)建新的列表,以此來解決上述的問題。
2.淺拷貝和深度拷貝問題

上述程序中,我們創(chuàng)建了字典dict1。并通過淺拷貝將dict1拷貝給dict2,通過copy庫中的deepcopy(深拷貝)將dict1拷貝給dict2。可當(dāng)刪除dict2中的鍵值為’2’中的子對象的元素后,dict1中的對應(yīng)元素也被刪除了,而dict3卻還保留。這就是淺拷貝和深拷貝的區(qū)別。如下圖所示。

淺拷貝只是拷貝了父對象,但是對于子對象還是引用的同一個對象。而對于深拷貝,則是完全將子對象和父對象拷貝了一份出來,各自都有獨(dú)立的子對象。
3.切記不要用官方庫文件名來命名自己的文件
這里的官方庫指的是大家需要import的庫,這里小編統(tǒng)稱為官方庫。如下圖所示。

小編創(chuàng)建了一個py文件,并命名為numpy。當(dāng)小編想要調(diào)用大名鼎鼎的“numpy”時,此時程序報(bào)了找不到屬性的“array”的錯誤。原因就是小編將自己的py文件命名為了numpy,程序便會自動的在當(dāng)前文件里面找“array”這個屬性。結(jié)果可想而知,當(dāng)然找不到啦,所以小編提醒大家,千萬不要將自己文件的名稱與官方庫撞名,不然會出大問題。
4.學(xué)會迭代器的使用
Python作為一個非常方便快捷的語言,很多元素都具有可迭代性,我們要充分利用好這些性質(zhì),如下圖所示。

我們想要對list對象中的所有元素執(zhí)行addOne函數(shù),傳統(tǒng)的也是標(biāo)準(zhǔn)的方法是利用for循環(huán)來實(shí)現(xiàn),就如第一種方法。但是由于list對象是可迭代對象,我們完全可以利用好這個優(yōu)勢,一行代碼就搞定這個問題,如第二種方法所示。所以充分利用好python中一些可迭代對象的性質(zhì),會節(jié)省很多的代碼,同時也讓我們少犯錯誤。
5.頻繁的使用全局變量
作為python的初學(xué)者,大家都喜歡定義全局變量,并在函數(shù)中改變?nèi)肿兞浚豢煞裾J(rèn)的是某些地方需要在函數(shù)中改變?nèi)肿兞浚沁@樣的方法會對程序帶來傷害,程序的安全性會變得脆弱。大家需要在平時的編程中改變這種習(xí)慣,如下圖所示。

在編程時,我們應(yīng)該盡量使用傳參的形式來使用全局變量,而不是直接修改全局變量。因?yàn)槿肿兞看蠖鄶?shù)情況下是所有的函數(shù)共享的變量,為了保證程序的安全,不應(yīng)該隨便被改變,除非在程序設(shè)計(jì)的時候,要求去改變?nèi)肿兞俊?/p>
6.明確是python2還是python3
在初學(xué)python的時候,大家可能會被python2還是python3搞得手足無措,無法及時的在python2和python3的語法中進(jìn)行切換,大家需要明確自己使用的python版本,因?yàn)閜ython2與python3區(qū)別還是比較多的,因此大家需要格外小心,如下圖所示。

由于python2和python3中的輸出表達(dá)形式不同,所以大家需要在使用print函數(shù)時,在python3版本后面加小括號進(jìn)行輸出。
7.分不清”is”和“==”的區(qū)別
對于“is”和“==”的使用 ,大家平時多用來判斷兩個值是否相等,但是這“相等”在python中也有不同的概念,我們要區(qū)分是地址相等還是數(shù)值相等,如下圖所示。

上述程序中我們分別利用is和==倆判斷兩個列表是否相等,可以看出,is是判斷兩個列表的地址是否相等,而==是看兩個列表中的數(shù)值是否一致。大家可以記住一個順口溜:is看地址,等號看內(nèi)容,這樣再使用is和==進(jìn)行元素判斷時就不會再犯錯誤了。
8.將python的關(guān)鍵字作為變量名稱
作為python的初學(xué)者,往往會搞不清楚python的關(guān)鍵字有哪些,從而會使得程序報(bào)錯。

上述的程序中,我們利用關(guān)鍵字“class”來創(chuàng)建新的類別,這會導(dǎo)致程序報(bào)錯,同時我們可以發(fā)現(xiàn),編輯器對于關(guān)鍵字的提示是不同的顏色提示,告訴我們使用的是關(guān)鍵字,從而讓我們注意不要使用關(guān)鍵字作為變量名稱。
9.使用未定義的局部變量
對于局部變量,我們在調(diào)用它的時候需要確保它被定義,如下圖所示。

對于printLocalNum1,我們沒有定義localnum就調(diào)用它 ,結(jié)果必然報(bào)錯,但是在printLocalNum2中,我們通過判斷輸入的大小,給localnum進(jìn)行賦值,然后輸出localnum的結(jié)果,這里,我們通過if else做了完全的判斷,確保無論在何種數(shù)值(注意必須是數(shù)值)輸入下,localnum都會被進(jìn)行賦值,從而不會調(diào)用未定義的localnum。
10.規(guī)避++操作和—操作

Python雖然語法簡單,但是對于C++、java中的++或者—的自增和自減操作是不支持的,原因是為什么呢?小編給大家一個我個人的理解,由于在python中整數(shù)是不可變類型,創(chuàng)建之后就不能被改變,而自增和自減就是將原先地址里的數(shù)值進(jìn)行改變替換,這與python不可變類型相違背,因此就無法實(shí)現(xiàn)自增或者自減操作了。
以上10條信息是小編個人在N年的漫長python學(xué)習(xí)生涯中總結(jié)出來的新手常見的錯誤,具有很高的代表性,希望大家能夠引以為戒,不要犯同樣的錯誤。






















