分享幾個Python小技巧函式裡的4個小花招

追憶MHyourh發表於2018-10-30

前面講了很多內容都是關於python的變數,資料結構,下面我們來談一談python的函式。python裡的函式知識點大概分為基礎的定義使用作用域引數傳遞高階用法,其中引數傳遞最為靈活,作用域最為繞人.


函式其實是對程式邏輯進行結構化或者過程化的一種程式設計方法,把整塊的程式碼巧妙的隔離成易於管理的小塊,是最基本的一種程式碼抽象的方式。

python函式是用def關鍵字定義的:

  • def算是函式的頭,頭上一般會有一個函式名,後面跟0個或者多個引數
  • 然後是函式的身體,這個程式碼塊就是函式的主體部分,一般會縮排寫
  • 最後是函式的尾巴包含一個return語句,返回一個物件的表示式.

今天我們先來說一說裡面的一些小花招,算是給初學者的開胃菜,為後面正式講函式熱熱身:

1.Python函式可以返回多個值

一般的程式語言比如c,c++,java,一般返回的都是一個值,python可以返回多個值(perl其實也可以),因為有的時候我們除了需要函式返回計算的結果,我們還需要返回一些操作的狀態,看個簡單的例子你就明白了 :

分享幾個Python小技巧函式裡的4個小花招

這個getHtmlResponse()函式可以返回多個值,第一值是返回處理的狀態True or false,第二值是msg,有的時候我們需要先判斷狀態,若true 就不管了,若是false再進一步處理.

這樣的場景下用函式返回多個值這個特性很容易搞定.原理其實就是函式返回了一個元組,然後把結果賦值給多個變數。

說到這裡,我穿插一個小技巧,我的時候我們希望丟棄掉一些返回值,

我們可以用_搞定(用一個幾乎用不到的變數名,來作為要丟棄的值的名稱)

分享幾個Python小技巧函式裡的4個小花招

2.儘量用異常表示特殊情況,不要返回None

python函式若你什麼都不return,預設返回None,很容易忽視這一點

分享幾個Python小技巧函式裡的4個小花招

有的同學說我寫函式程式碼,會記得加上None,但是有的時候返回None也會讓你誤解,不好處理,你不信我們看下面一個例子:

分享幾個Python小技巧函式裡的4個小花招

原因是當分子為0的時候,計算結果為0,那這個結果去做條件判斷時,會出現問題,會弄巧成拙。其實你返回None是有特殊意義的,是為了判斷分母為0.

解決這個問題有兩個辦法:第一個是把返回值拆成兩部分,返回一個元組,第一個元素是操作是否成功,第二個是執行結果,改成如下:

分享幾個Python小技巧函式裡的4個小花招

第二個好的辦法是:根本不返回None,直接拋異常給上一級,使得呼叫者必須應對它,好我們來改一下程式碼看看:

#異常部分後面會講,valueError是異常中的一種,表示傳給函式的引數型別不正確

分享幾個Python小技巧函式裡的4個小花招

現在呼叫者就需要處理因輸入值無效而引發的異常,而不需要用條件語句去判斷函式的返回值,非常清晰而且不容易混淆.

3.匿名函式

python除了def語句之外,還提供了一中懶人專用的函式叫做lambda,有點LISP語言的風格

(LISP是一個非常著名的
黑客語言)
.所以稱為lambda匿名函式,其實就想def一樣,這個表示式建立了一個能夠呼叫的函式,它其實是返回一個函式而不是像傳統的函式賦值給一個變數名,所以一般都是在一種行內進行使用.

形式:

lambda arg1,arg2...argN:expression using arg
複製程式碼
  • lambda是一個表示式,而不是一個語句

作為一個表示式,經常在列表中或者函式中呼叫,能夠出現在python語法不允許出現def的地方.此外做為一個表示式lambda返回了一個值(新的函式),可以選擇性的賦值給一個變數名。

  • lambda的主體是單個的表示式,而不是程式碼塊

lambda的主體簡單的就像放在def主體的return 裡的程式碼一樣,寫成一個表示式,lambda通常比def功能要小,只能封裝一些有限的邏輯,lambda為簡單任務而生,def則處理更大更復雜的任務.

對比一下吧:

  • 普通函式
分享幾個Python小技巧函式裡的4個小花招

  • 匿名函式
分享幾個Python小技巧函式裡的4個小花招

在比如在排序對資料整理時經常用到:

分享幾個Python小技巧函式裡的4個小花招

也許懶惰也是推進人類進步的一大利器,當年因為懶惰嫌Dos太麻煩才有了win,當年的手機系統因為懶惰希望不用鍵盤直接手點點多好才有了觸控式螢幕,因為懶惰懶的打字才推進了語音識別.

4.警惕預設引數的潛在問題

最後一個花招是很具有迷惑性的,一定要看仔細,一般我們在函式引數傳遞的時候,希望用一種非靜態的型別來作為關鍵字的預設值,比如我們經常會有列印日誌訊息的函式:

分享幾個Python小技巧函式裡的4個小花招

奇怪兩條訊息戳是一樣的,這是因為datetime.datetime.now()只執行了一次,也就是說在函式定義的時候執行了一次。引數的預設值會在每一個模組載入進來的時候求出,一旦這段模組載入進來了引數的預設值就很固定了,程式不會再出執行datetime.datetime.now()

是不是覺得很冤枉,

明明想動態的一下的,反而變成了靜靜~~
腫麼辦

這裡有一個小技巧,在Python中若你想動態實現預設值,習慣把預設值改成None,然後加一些註釋,看程式碼吧:

分享幾個Python小技巧函式裡的4個小花招

現在兩條訊息的時間戳就不同了,如果引數的實際預設值是可變型別,切記切記用None作為形式上的預設值.

好了函式裡的小花招就講到這裡啦,希望能給初學者一些啟發,若有什麼不懂的,也可以留言跟我探討交流.


相關文章