[21] Python函數(二)

1. 概述

本章將繼續介紹函數。另外我的筆記本壞了,用了五年半的Macbook徹底拜拜了,心疼啊……

  • 計算機編程的原理簡要介紹
  • 集成開發環境PyCharm
  • 變數名、數字、字元串、列表
  • 句式、注釋
  • 輸入和輸出
  • 條件判斷語句
  • 循環語句
  • 各類數據結構
  • 函數
  • 模塊和引入

2. 參數

參數(parameter)是函數的重要組成部分之一,參數視情況可有可無,但是生活中大部分情況參數是必不可少的,比如一元二次方程之根的判別式:

Delta=b^{2}-4ac

想要判斷一個一元二次方程是有實數根還是複數根,有幾個根,我們必須先算delta的值,而要算delta,我們則要知道a、b、c。這裡的a、b、c就是我們說的用於算delta的參數。更抽象的例子還有f(x)=2x+3, f(x,y)=x/y+1等,也就是括弧里的倆變數,我們就叫其該函數的參數。

在Python中,含有參數的函數定義方法如下:

def function_name(param1, param2, param3, ...):n

首先告訴Python這是函數,寫上def;其次輸入函數名,Python函數命名規則和變數差別不大,一般函數和一般變數我們推薦用小寫和下劃線組合起來;最後括弧里寫上各個參數名,有幾個寫幾個。

參數會被作為變數在該函數內部被使用。

我們來寫一個根的判別式的函數,輸入a、b、c,判斷根的性質。

# ax^2 + bx + c = 0ndef determine_roots(a, b, c):n delta = b ** 2 - 4 * a * cn if delta > 0:n print(It has two distinct real roots.)n elif delta == 0:n print(It has exactly one real root.)n else:n print(It has two distinct complex roots.)nn# Main program starts heren# 2x^2 + 3x + 5 = 0ndetermine_roots(2, 3, 5)n# 2x^2 + 3x - 5 = 0ndetermine_roots(2, 3, -5)n# 2x^2 + 4x + 2 = 0ndetermine_roots(2, 4, 2)n

最後結果如下,一一對應各行:

It has two distinct complex roots.nIt has two distinct real roots.nIt has exactly one real root.n

參數的數據傳遞其實很簡單,位置對應上就行了,比如determine_roots(2, 3, 5)中,我們雖然沒有寫a、b、c哪個是哪個,只寫了三個數字,但Python自己會默認把在第一個數字賦值給第一個參數,第二個數給第二個參數,以此類推。當然我們也能用變數:

# 2x^2 + 3x + 5 = 0ncoeff_2 = 2ncoeff_1 = 3ncoeff_0 = 5n# Call functionndetermine_roots(coeff_2, coeff_1, coeff_0) # It has two distinct complex roots.n

雖然函數名不一樣,但是我們還是能在運行該函數時,讓Python清楚地知道a對應coeff_2,b對應coeff_1,c對應coeff_0,把主程序變數的值按照位置順序借給這些參數,然後直接使用參數名計算。

當然,有強迫症的同學們非得在主程序中也使用和函數的參數一樣的變數名,也不是不可以,畢竟很多情況下,主程序中的變數命名和子程序(函數)中的變數命名沒有關係,由於是把主程序的值複製給參數,函數中同樣名字的變數值發生改變並不會影響主程序中相同名字的變數。當然也有例外,不過現在畢竟是入門,我們暫時只需要知道這一點。

我們看一下如果把倆參數交換一下會發生啥事,

a = 2; b = 3; c = 5ndetermine_roots(a, b, c) # It has two distinct complex roots.ndetermine_roots(a, c, b) # It has two distinct real roots.n

結果會發生改變,這個例子可以看出,參數的值是按照位置對應起來的,和主程序變數名是否一樣沒有關係,他們對應的只是位置相同地方的數據,而非指代數據的變數的名字。第一行對應2x^2+3x+5=0,第二行其實對應的是2x^2+5x+3=0。

當然我們也有辦法讓位置即使錯亂也能準確對應,不過很多情況下沒有必要,我會在下一篇提及,這裡我們只需要知道我上面說的就行。

3. 返回值

另外一個重要的組成部分即為返回(return)語句。我們不可能一直像之前寫的函數一樣,使喚一個函數後輸出值就結束了,很多時候我們需要該函數計算出一個數據,能在主程序中繼續利用。這時候我們就用

return valuen

來實現回收利用函數中計算出來的值。

# ax^2 + bx + c = 0ndef determine_roots(a, b, c):n delta = b ** 2 - 4 * a * cn return deltan

我們有了a、b、c,我們可以拿它來算出delta,並返回delta的值。為什麼叫「返回」?原因是我們主程序運行著運行著,由於召喚了函數,所以程序就會帶著參數的值跑去函數里運行函數的代碼,運行完函數代碼後,就會回到主程序中剛才跑出來的位置那裡,繼續運行下面的程序。

delta1 = determine_roots(a, b, c)n

有了return,我們就可以讓函數計算出某個數據後,將該數據作為計算出的結果賦值給主程序中的變數。

當然,return的含義就是拿著結果回到主程序中,函數在運行中一旦碰到return並成功執行return,這次函數就運行結束了,return下面的屬於的該函數的語句一概不運行。

# ax^2 + bx + c = 0ndef determine_roots(a, b, c):n delta = b ** 2 - 4 * a * cn return deltan print(Do I still belong here?)n

最後那個print按照縮進屬於該函數,但是由於其運行的時候勢必要在return之後運行,PyCharm會告訴你這一行寫在那用於不會被執行到。

這麼說我們可能感覺一個函數只能有一個return,但是如果我們能和條件語句或者循環語句結合起來,一個函數或許能有多個return,但這是後話,我們先理解怎麼使用return就行。

如果我們沒有值返回,比如之前寫的程序,一堆print之後就完事了,我們如果有強迫症,可以在函數最後加上就單個詞return:

def burger():n print(Burger is tasty)n returnn

這個return後面啥也沒有,我們就可以直接一身輕鬆兩手空空返回到召喚處,啥事也沒有。有時候return後面也可以跟一個公式,運算順序是計算出公式的值後,返回該值。

# ax^2 + bx + c = 0ndef determine_roots(a, b, c):n return b ** 2 - 4 * a * cn

這和上面先算給delta再返回delta運算結果完全一樣。

有了這返回我們就能隨心所欲使用函數了。

# ax^2 + bx + c = 0ndef determine_roots(a, b, c):n return b ** 2 - 4 * a * cnndef calc_roots(a, b, delta):n root1 = (-b + delta ** 0.5) / (2 * a)n root2 = (-b - delta ** 0.5) / (2 * a)n return root1, root2 # result as a tuplenn# Main program starts heren# x^2 - 3x - 10 = 0ndelta = determine_roots(1, -3, -10)nresult = calc_roots(1, -3, delta)nprint(result)nn# 2x^2 - 4x + 2 = 0ndelta = determine_roots(2, -4, 2)nresult = calc_roots(2, -4, delta)nprint(result)n

結果為:

(5.0, -2.0)n(1.0, 1.0)n

當然這裡複數暫時不在我們考慮範圍內,雖然這個能算,但是由於Python中冪的編譯的原因,複數的計算結果不是我們正好想要的結果,而是一個帶有一個誤差值的結果。不過這不重要,我們只要知道返回值的作用是讓函數能夠計算出結果,當運行完函數後,該函數便可以代表該數據。

最後看一個:

# Main program starts heren# x^2 - 3x - 10 = 0nresult = calc_roots(1, -3, determine_roots(1, -3, -10))nprint(result)n

我們少了一個delta變數,但結果還是一樣的,我們首先傳遞參數,傳遞著傳遞著看到程序要用函數了,於是帶著1、-3、10跳進determine_roots函數,計算出結果後返回計算出的值,此時在主程序中,determine_roots(1, -3, -10)就相當於計算出的49這個數,然後我們帶著1、-3、49計算結果。

當然我們還能更簡潔,

# x^2 - 3x - 10 = 0nprint(calc_roots(1, -3, determine_roots(1, -3, -10)))n

結果也是一樣。不過這麼做的缺點就是不能繼續利用這個值了,這就得看我一開始寫的Python變數那一章了,變數的作用就是能存值方便以後利用。

我會在接下來一篇介紹不定量參數和默認參數,以及包含多個返回語句的函數。


推薦閱讀:

跟黃哥學習python第三章
Python tricks ——淺談Python加速
GlumPy 中文文檔翻譯:上手簡介
小心了!小白無法入門Python你不可避免的4個陷阱
數據科學導論:序章

TAG:Python | 计算机科学 | 编程 |