沒有學不會的python
函數是什么?
老調常談,還是那老一套,學習一個東西前,先搞懂是什么,再來學習怎么用。
函數函數,如果你是剛經歷過高考肯定很熟悉,數學中就經常出現這個名詞,比如什么sin函數,cos函數之類的。哈哈,心疼一會高考生。
函數是什么呢?其實函數嚴格來說,可以分為數學函數以及計算機函數,數學函數嘛,大家都是有文化的人,應該都知道,且我講的是編程,數學函數跟這個關系不大,這里就略過了。我們主要講計算機函數。
計算機函數是什么?
官方的解釋是這樣的:
函數是指一段在一起的、可以做某一件事兒的程序。也叫做子程序、(OOP中)方法。
其實這段解釋已經很直白了,對于初學者來說,困惑的點就是子程序這個詞。在寫代碼的過程中,往往由于業務邏輯比較復雜,各種數據交互流程比較繁瑣,出于數據安全、易于理解、松耦合、強內聚等特征的考慮,我們會把程序劃分成多個模塊,每個模塊又劃分多個類和多個函數。由于上述現象的出現,一個大的程序模塊就有很多小的模塊組成,然后在大的模塊中會調用小的模塊以實現某個功能點,此時小的模塊就成為了子模塊,也叫做子程序。
簡單說吧,子程序就是一個實現特定功能的程序塊,通常被主程序調用。
嗯,現在把子程序講清楚了,那么這個跟函數有什么關系?其實吧,子程序換一種說法,也可以稱作是函數。在不同的語言中,有時也稱為方法,但在python中,如果子程序是處于模塊中的就稱作函數,如果是處于類中的,就稱作方法。由于我這個系列里還沒講到面向對象,所以,我們忽略掉類的方法這個說法,現在暫且認為,子程序就是函數。
做一個比較形象的例子:

假設上述人的一天是主函數,那么吃飯上班睡覺就是子函數,只有在主函數中調用了子函數,才能組成人的一天。
函數有什么作用?
既然函數存在,那么就有它存在的道理。它的作用不僅有,而且特別重要。下面就隨便列幾個,更多的我就不說了,因為如果你沒有編程基礎的話,很多特性說了也理解不了,等于白說。
- 高內聚、低耦合---這個是編程語言中的一個非常重要的特征,尤其是面向對象語言中。高內聚指的是,實現同樣目的的代碼應該盡量放在一塊,不要松散。低耦合指的是,函數與函數之間盡量解耦,不要處處關聯,這樣才不會出現一發而觸動全身的情況。即不會因為改了某個函數的一句話,導致其它函數也不能用了。
- 易拓展---需求是跟著市場和甲方走的,產品要改需求,程序員就得加班,如果程序的代碼結構很好,那么我們就可以只改需要改的函數,其它的不動,比如增加功能模塊,增加參數。
- 可重復使用---當把某個功能代碼高度集中在函數里面時,此函數就不依賴于其它函數而存在,因此,任何需要實現該功能的函數都可以通過調用這個函數來獲取該功能。
- 易于理解---通過函數名稱以及文檔描述和注釋,可以讓自己以外的人更好的參與進來,而函數的存在,對于這種分工合作是個很好的表現形式,大家都不需要知道函數怎么實現的,只需要調用就可以了。
還有更多,以后你就會慢慢發現了。
如何定義函數?
函數的定義很簡單,看下面:
def function_name(prama1,prama2): pass
def的意思就是聲明后面的語句塊是一個函數,function_name就是函數名稱,param1、param2就是參數。到了這里,我有必要再說一下,因為面對著沒有基礎的同學,難免要多說一點,避免他們走彎路。我要說的是函數名稱不是寫死的function_name,上面的只是一種表現形式。就好比大家都有名字,但是我們大家都不叫名字,有的叫劉亦菲,有的叫馬云。函數名稱應該是根據所實現的功能來定的,參數名稱也類似。
這里說一下什么叫做參數,參數可以看作是一個因變量,只有傳入了參數,才能使函數產生不同的結果。參數不是函數必須的,可以構造一個不需要參數的函數,但是這個函數總會產生相同的結果。
下面看一下函數的示例:
def my_sum(param1, param2): return param1 + param2def my_diff(param1, param2): return param1 - param2
完了嗎?那肯定不是,哪有這么簡單。結合我自己的編程經驗,還有以下的功力要傳授給你們。
函數名稱要有實際意義,切記假大空,更忌諱的是取一個毫無關系的名字
比如:我想定義一個掃描字符串的每個字符并輸出的函數。有下面三個寫法:
def scan_str(content): for s in content: print(s)def scan(content): for s in content: print(s)def a(content): for s in content: print(s)
第一個函數最優,從名字就看得出來就是掃描字符串。第二個次之,從名字看到出來是掃描,但是掃描啥不知道,掃描文件還是掃描病毒還是其他的?這就是范圍過廣,也就是假大空。第三個寫出來是要被罵的,而且是往死里罵的那種,從函數名字根本看不出來是什么意思。你想象一下啊,如果一個幾萬行代碼含有幾百個函數的程序,全部名字都是abcd這樣的名字,你會不會看瘋掉?
函數應該要加上文檔說明,復雜的語句要加上注釋說明
這么做的原因是,一來方便日后自己查看代碼,二來是方便別人接手你的代碼。添加文檔說明的方式如下:
def scan_str(content): """ 掃描字符串的每個字符并輸出 :param content: 待掃描的內容 :return: 不返回任何結果 """ for s in content: print(s)
就是在函數聲明下面,真正的代碼實現邏輯上面,輸入三次雙引號就會自動生成一個待填充的文檔說明結構,含有功能描述,參數描述以及返回值描述。未填充前的代碼是這樣的:
def scan_str(content): """ :param content: :return: """ for s in content: print(s)
函數的代碼塊不易過長,一般維持在15行以內為佳
代碼語句塊過長說明我們的功能劃分的還不夠細致,過于短說明我們過于精簡,一般維持在15行以內為佳。當然這不是硬性標準,它不會報任何異常。只是這個是默認的python pep8國際編碼規范,很多大公司都會有代碼規范考核的,從一開始掌握這些對我們有好處。 是
函數的參數值和傳參
上面有簡單講了參數是什么。但這還遠遠不夠,python中的參數,是非常靈活且有趣的。目前來說,可分為四類,分別是必須參數、可選參數、位置參數、關鍵詞參數。下面就這些一個個來說。
必須參數
必須參數就是必須要傳遞的參數,如果不傳遞就調用函數會報TypeError。比如我如果這樣調用函數,就會報錯:
def scan_str(content): """ 掃描字符串的每個字符并輸出 :param content: 待掃描的內容 :return: 不返回任何結果 """ for s in content: print(s)scan_str()
由于scan_str有一個content參數,這個是必須參數,如果你不傳遞就調用這個函數,會爆出如下異常:
Traceback (most recent call last): File "D:/code/python/blog/main.py