【Think Python】Python筆記(六)有返回值的函數

(一)返回值

調用一個有返回值的函數會生成一個返回值;通常將這個返回值賦值給變量或者作爲表達式的一部分;

def area(radius):
    a = math.pi * radius**2
    return a
  • return語句意味着:立即從該函數返回,並且使用接下來的表達式作爲返回值;返回值可以是任意複雜的;
  • 在一個有返回值的函數中,最好保證程序執行的每一個流程都最終碰到一個return;【充分考慮好每一種分支情況】

(二)增量式開發(incremental development)

  • 隨着函數越來越複雜,調試的時間會越來越多;爲了應對負載的程序,可以嘗試增量式開發;
  • 增量式開發的目標,是通過每次只增加和測試少量代碼,來避免長時間的調試;
  • 比如,在寫一個函數的時候,可以先寫一下這個函數的函數頭和形參,函數體可以用pass或者其他的return語句進行代替;當這個函數頭可以運行的時候,再往函數體中增加代碼;
  • 當然上面的只是一個簡單的類比,只是一種簡單的思路:當想要實現一個功能的時候,尤其是複雜的功能,不要想着一步到位,可以將這個功能進行分解,或者先實現一個框架,之後再逐步完善細節;
  • 增量式開發的關鍵:
    1. 從一個能運行的程序開始,並且每次只增加少量改動。無論你何時遇到錯誤,都能夠清楚定位錯誤的源頭;
    2. 使用臨時變量存儲中間值,這樣能顯示並檢查它們;
    3. 一旦程序能夠正確運行,就要刪除一些腳手架(scaffolfing)代碼;或者將多條語句組合成爲複合表達式,當然,前提是不影響程序的可讀性;

(三)組合

  • 我們可以從一個函數的內部調用另一個函數;
  • 一些臨時變量對於開發很有用,但是一旦程序正確運行了,我們可以通過合併函數調用,使得程序更加簡潔;

(四)布爾函數

  • 這種類型的函數可以返回布爾類型(booleans),通常對於隱藏函數內部的複雜測試代碼非常有用;
  • 布爾函數通常用於條件語句中;
def is_divisible(x, y):
	if x%y == 0:
        return true;
    else:
        return false;

==的返回值是Boolean類型,可以直接使用這個來簡化上面的代碼:

def is_divisible(x, y):
    return x % y == 0

(五)再談遞歸

到目前爲止,雖然學到的知識Python中很小的一個子集,但是實際上,這已經是一個完備的編程語言,這意味着任何能夠被計算的東西都可以用這個語言表達;

  • 使用遞歸計算階乘:
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)
  • 程序的執行過程:【假如n == 3】

  • 堆棧圖:

(六)信任之躍【一種閱讀代碼的方法】

  • 跟隨程序的執行流程讀代碼,是一種方法,但是可能很快就會變得錯綜複雜;
  • 另一種方法:當遇到一個函數的時候,不去跟蹤函數的執行流程,而是假設這個函數正確運行並且返回了正確的結果;
  • 事實上,使用內建函數的時候已經使用的了這種方法,我們總是假設,這個內建函數的執行是正確的;
  • 使用遞歸函數也是一樣的,我們不再順着執行流程,而是假設每次遞歸都能正確執行;

(七)斐波那契數列【遞歸】

def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacii(n-1)+fibonacci(n-2)

(八)檢查數據類型

  • 上面的函數中,當輸入的參數是一個非整數的時候,這時候,遞歸將無限進行下去,因爲沒有邊界;
  • 我們需要檢查傳入的參數是不是我們所希望的類型;
  • 我們使用內建函數isinstance來驗證實參的類型:
def factorial(n):
    if not isinstance(n, int):
		print('Factorial is only defined for integers.')
        return None
    elif n<0:
         print('Factorial is not defined for negative integers.')
         return None
    elif n == 0:
        return 1
    else:
        return factorial(n-1)*n
  • 上面的方法有時候稱之爲“監護人(Guardian)模式;通過設置監護人,保證後面的代碼不會出現錯誤;
  • 當然還有更加靈活的方式:拋出異常

(九)調試

將一個大程序分解爲若干較小的函數,爲程序的調試生成的自然的檢查點;當一個程序不能如預期運行的時候,需要考慮的情況:

  1. 該函數獲取的實參有問題,違反先決條件;
  2. 該函數有些問題,違反後置條件;
  3. 返回值或者使用方法有問題;

實參問題

爲排除這種可能性,可以在函數的開始增加一條print語句,打印形參的值或者類型

函數問題

如果函數的形參沒有問題,則在函數的return之前,打印結果、返回值;考慮用一些簡單的值調用這個函數;

調用問題

要確保返回值被正確地使用;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章