每天一小时python官方文档学习(三)————函数
上一天看到第四章的一半,介紹了一些常用的流程控制工具,也就是常用語句,主要是if、for、range()、break、continue、else和pass。今天把第四章剩下的看完,講的是如何在python中定義和使用函數。函數其實就是一種對代碼的封裝,對于一段完成某種功能的代碼,如果需要在程序中多次用到這個功能,不使用函數的話,就要寫多次相同的代碼,很麻煩;如果使用函數的話,定義函數只需要一次,往后每次需要使用這個函數的話調用就行了,即實現了代碼重用,簡便很多。
4.6. 定義函數
python中,我們使用關鍵字 def 引入一個函數定義。它必須后跟函數名稱和帶括號的形式參數列表。構成函數體的語句從下一行開始,并且必須縮進。
函數體的第一個語句通常是注釋或者幫助文檔,用三引號‘’‘ ’‘’括起來,里面應該寫上函數的功能和各參數的意義等等,是面向用戶的。在notebook里面使用help()就可以查看到這些信息。寫幫助文檔是一個應該養成的好習慣。
函數調用(執行)則是直接運行函數名,如果有參數則寫在括號內,一個用于輸出斐波拉契數列的函數例子如下:
>>> def fib(n): # 函數定義 ... """函數功能:打印n以內的斐波拉契數列""" ... a, b = 0, 1 ... while a < n: ... print(a, end=' ') ... a, b = b, a+b ... print() ... >>> # 函數調用 ... fib(2000) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597定義了的函數是一個特定的類型,它也支持重命名,如下f和fib就是同一個函數了:
>>> fib <function fib at 10042ed0> >>> f = fib >>> f(100) 0 1 1 2 3 5 8 13 21 34 55 89學過其他語言的人可能會問,python的函數有返回值嗎?答案是肯定的,我們可以用return語句返回指定的值,如果像上面的例子一樣沒有return呢?實際上也有返回值,只不過是一個None而已,使用print()就可以看到它了。
總結一句:return 語句會從函數內部返回一個值。 不帶表達式參數的 return 會返回 None。 函數執行完畢退出也會返回 None。
>>> fib(0) >>> print(fib(0)) None最后我們改寫上面的斐波拉契函數,不是直接打印print(),而是先調用函數返回return一個列表,再打印這個列表:
>>> def fib2(n): # 函數定義 ... """函數功能:返回一個列表,里面包含了n以內的斐波拉契數列""" ... result = [] ... a, b = 0, 1 ... while a < n: ... result.append(a) # 向列表新增一個數據 ... a, b = b, a+b ... return result ... >>> f100 = fib2(100) # 函數調用 >>> f100 # 打印結果 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]4.7. 函數定義的更多形式
4.7.1. 參數默認值
最有用的形式是對一個或多個參數指定一個默認值。這樣創建的函數,可以用比定義時允許的更少的參數調用,比如:
def ask_ok(prompt, retries=4, reminder='Please try again!'):while True:ok = input(prompt)if ok in ('y', 'ye', 'yes'): # in關鍵字可以測試一個序列是否包含某個值return Trueif ok in ('n', 'no', 'nop', 'nope'):return Falseretries = retries - 1if retries < 0:raise ValueError('invalid user response')print(reminder)這個函數可以通過幾種方式調用:
- 只給出必需的參數(參數prompt):ask_ok('Do you really want to quit?')
- 給出一個可選的參數(參數prompt和retries):ask_ok('OK to overwrite the file?', 2)
- 或者給出所有的參數(參數prompt、retries和reminder):ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')
有兩點需要注意!!
一、默認值是在 定義過程 中在函數定義處計算的,所以以下結果會打印5而不是6:
i = 5def f(arg=i): # 此處傳入默認值i,所以arg=i=5print(arg)i = 6 # 不影響f的默認值 f()二、默認值只會執行一次。這條規則在默認值為可變對象(列表、字典以及大多數類實例)時很重要。比如,下面的函數會存儲在后續調用中傳遞給它的參數:
def f(a, L=[]):L.append(a)return Lprint(f(1)) print(f(2)) print(f(3))打印結果為:
[1] [1, 2] [1, 2, 3]如果你不想要在后續調用之間共享默認值,你可以這樣寫這個函數:
def f(a, L=None):if L is None:L = []L.append(a)return L打印結果為:
[1] [2] [3]4.7.2. 關鍵字參數
4.7.3. 特殊參數
這兩節已經在我之前的文章中介紹過了,感興趣的小伙伴可以去看看:
python函數參數那些事,關鍵字參數與位置參數
4.7.4. 任意的參數列表
最后,最不常用的選項是可以使用任意數量的參數調用函數。這些參數會被包含在一個元組里(參見 元組和序列 )。在可變數量的參數之前,可能會出現零個或多個普通參數。:
def write_multiple_items(file, separator, *args):file.write(separator.join(args))一般來說,這些可變參數 將在形式參數列表的末尾,如上面代碼中的*args參數(和C語言區分一下,注意不是指針)。因為它們收集傳遞給函數的所有剩余輸入參數,簡單來說,就是撿破爛的,剩下的參數都歸他了。
但也有例外,它不在參數列表的末尾。此時,出現在 *args 參數之后的任何形式參數都是 僅關鍵字參數,也就是說它們只能作為關鍵字參數而不能是位置參數:
4.7.5. 解包參數列表
如果我們的參數已經在列表或元組里了,但是想把里面的元素作為單獨的參數傳入函數,應該怎么做呢?此時稱為對參數列表進行解包。
例如,內置的 range() 函數需要單獨的 start 和 stop 參數。如果它們不能單獨使用,可以使用 *操作符 來編寫函數調用以便從列表或元組中解包參數:
如果參數在字典里,則用**操作符解包出字典的值value,來提供關鍵字參數:
>>> def parrot(voltage, state='a stiff', action='voom'): ... print("-- This parrot wouldn't", action, end=' ') ... print("if you put", voltage, "volts through it.", end=' ') ... print("E's", state, "!") ... >>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"} >>> parrot(**d) -- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !4.7.6. Lambda 表達式
可以用 lambda 關鍵字來創建一個小的匿名函數。Lambda函數可以在需要函數對象的任何地方使用。它們在語法上限于單個表達式。從語義上來說,它們只是正常函數定義的語法糖。與嵌套函數定義一樣,lambda函數可以引用所包含域的變量。
簡單來說,Lambda函數有兩個作用:返回一個函數,或者傳遞一個小函數作為參數。
作用1:
作用2:
>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')] >>> pairs.sort(key=lambda pair: pair[1]) >>> pairs [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]4.7.7. 文檔字符串
4.7.8. 函數標注
這兩節介紹的是關于函數幫助文檔和注釋內容和格式的一些約定,這里不詳細展開了。
總結
以上是生活随笔為你收集整理的每天一小时python官方文档学习(三)————函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 嵌入式工业平板电脑的日常维护嵌入式工业平
- 下一篇: 每天一小时python官方文档学习(四)