欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

廖雪峰Python教程筆記(三)

系統 2189 0

廖雪峰Python教程筆記(三)

  • 5 函數

5 函數

基本上所有的高級語言都支持函數,Python也不例外。Python不但能非常靈活地定義函數,而且本身內置了很多有用的函數,可以直接調用。

抽象
計算數列的和,比如:1 + 2 + 3 + … + 100
在這里插入圖片描述
看到 ∑ 就可以理解成求和
借助抽象,我們才能不關心底層的具體計算過程,而直接在更高的層次上思考問題。

函數就是最基本的一種代碼抽象的方式。

調用函數
要調用一個函數,需要知道函數的名稱和參數,比如求絕對值的函數abs
廖雪峰Python教程筆記(三)_第1張圖片
調用函數的時候,如果傳入的參數數量不對,會報TypeError的錯誤:
abs() takes exactly one argument (2 given)

果傳入的參數數量是對的,但參數類型不能被函數所接受,也會報TypeError的錯誤:
bad operand type for abs(): ‘str’

而max函數max()可以接收任意多個參數,并返回最大的那個:
廖雪峰Python教程筆記(三)_第2張圖片
數據類型轉換
比如int()函數可以把其他數據類型轉換為整數:
廖雪峰Python教程筆記(三)_第3張圖片
函數名其實就是指向一個函數對象的引用,完全可以把函數名賦給一個變量,相當于給這個函數起了一個“別名”:
在這里插入圖片描述

定義函數 ;在Python中,定義一個函數要使用def語句,依次寫出函數名、括號、括號中的參數和冒號:然后,在縮進塊中編寫函數體,函數的返回值用return語句返回。
以自定義一個求絕對值的my_abs函數為例:
廖雪峰Python教程筆記(三)_第4張圖片

函數體內部的語句在執行時,一旦執行到return時,函數就執行完畢,并將結果返回。因此,函數內部 通過條件判斷和循環可以實現非常復雜的邏輯 。

如果沒有return語句,函數執行完畢后也會返回結果,只是結果為None。return None可以簡寫為return。

空函數
如果想定義一個什么事也不做的空函數,可以用pass語句:
在這里插入圖片描述
pass語句什么都不做,那有什么用?實際上pass可以用來作為占位符,比如現在還沒想好怎么寫函數的代碼,就可以 先放一個pass,讓代碼能運行起來。

參數檢查
調用函數時,如果參數個數不對,Python解釋器會自動檢查出來,并拋出TypeError:
但是如果參數類型不對,Python解釋器就無法幫我們檢查。試試my_abs和內置函數abs的差別:
廖雪峰Python教程筆記(三)_第5張圖片
傳入了不恰當的參數時,內置函數abs會檢查出參數錯誤,而我們定義的my_abs沒有參數檢查,會導致if語句出錯,出錯信息和abs不一樣。所以,這個函數定義不夠完善。

讓我們修改一下my_abs的定義,對參數類型做檢查,只允許整數和浮點數類型的參數。數據類型檢查可以用內置函數isinstance()實現:
廖雪峰Python教程筆記(三)_第6張圖片
添加了參數檢查后,如果傳入錯誤的參數類型,函數就可以拋出一個錯誤:
廖雪峰Python教程筆記(三)_第7張圖片
TypeError: bad operand type
錯誤和異常處理將在后續講到。

返回多個值
函數可以返回多個值嗎?答案是肯定的。
比如在游戲中經常需要從一個點移動到另一個點,給出坐標、位移和角度,就可以計算出新的坐標:
廖雪峰Python教程筆記(三)_第8張圖片
import math語句表示導入math包,并允許后續代碼引用math包里的sin、cos等函數。
廖雪峰Python教程筆記(三)_第9張圖片
這只是一種假象,Python函數返回的仍然是單一值:原來返回值是一個tuple
廖雪峰Python教程筆記(三)_第10張圖片
小結:
1.定義函數時,需要確定函數名和參數個數;
2.如果有必要,可以先對參數的數據類型做檢查;
3.函數體內部可以用return隨時返回函數結果;
4.函數執行完畢也沒有return語句時,自動return None。
5.函數可以同時返回多個值,但其實就是一個tuple。
廖雪峰Python教程筆記(三)_第11張圖片

**函數的參數:**除了正常定義的必選參數外,還可以使用默認參數、可變參數和關鍵字參數,使得函數定義出來的接口,不但能處理復雜的參數,還可以簡化調用者的代碼。

位置參數
一個計算x2的函數:
在這里插入圖片描述
對于power(x)函數,參數x就是一個位置參數。
當我們調用power函數時,必須傳入有且僅有的一個參數x:
在這里插入圖片描述
如果要計算x4、x5……怎么辦?我們不可能定義無限多個函數。
可以把power(x)修改為power(x, n),用來計算xn,說干就干:
廖雪峰Python教程筆記(三)_第12張圖片
修改后的power(x, n)函數有兩個參數:x和n,這兩個參數都是位置參數,調用函數時,傳入的兩個值按照位置順序依次賦給參數x和n。

默認參數
新的power(x, n)函數定義沒有問題,但是,舊的調用代碼失敗了,原因是我們增加了一個參數,導致舊的代碼因為缺少一個參數而無法正常調用:
TypeError: power() missing 1 required positional argument: ‘n’

這個時候,默認參數就排上用場了。由于我們經常計算x2,所以,完全可以把第二個參數n的默認值設定為2:
廖雪峰Python教程筆記(三)_第13張圖片
這樣,當我們調用power(5)時,相當于調用power(5, 2):
廖雪峰Python教程筆記(三)_第14張圖片
設置默認參數時,有幾點要注意:
一是必選參數在前,默認參數在后,否則Python的解釋器會報錯
二是如何設置默認參數。
當函數有多個參數時,把變化大的參數放前面,變化小的參數放后面。變化小的參數就可以作為默認參數。
使用默認參數有什么好處?最大的好處是能降低調用函數的難度。

一年級小學生注冊的函數,需要傳入name和gender兩個參數:
在這里插入圖片描述
廖雪峰Python教程筆記(三)_第15張圖片
如果要繼續傳入年齡、城市等信息怎么辦?這樣會使得調用函數的復雜度大大增加。

我們可以把年齡和城市設為默認參數:
廖雪峰Python教程筆記(三)_第16張圖片
廖雪峰Python教程筆記(三)_第17張圖片
只有與默認參數不符的學生才需要提供額外的信息。

默認參數有個最大的坑,演示如下:
先定義一個函數,傳入一個list,添加一個END再返回:
在這里插入圖片描述
ZZZZZZZZZZZ
再次調用add_end()時,結果就不對了:
在這里插入圖片描述
Python函數在定義的時候,默認參數L的值就被計算出來了,即[],因為默認參數L也是一個變量,它指向對象[],每次調用該函數,如果改變了L的內容,則下次調用時,默認參數的內容就變了,不再是函數定義時的[]了。
在這里插入圖片描述
在這里插入圖片描述 無論調用多少次,都不會有問題:

可變參數
以數學題為例子,給定一組數字a,b,c……,請計算a2 + b2 + c2 + ……。
廖雪峰Python教程筆記(三)_第18張圖片
廖雪峰Python教程筆記(三)_第19張圖片
所以,我們把函數的參數改為可變參數:
廖雪峰Python教程筆記(三)_第20張圖片
定義可變參數和定義一個list或tuple參數相比,僅僅在參數前面加了一個*號。在函數內部,參數numbers接收到的是一個tuple,因此,函數代碼完全不變。
在這里插入圖片描述
廖雪峰Python教程筆記(三)_第21張圖片

*nums表示把nums這個list的所有元素作為可變參數傳進去。這種寫法相當有用,而且很常見。

關鍵字參數
關鍵字參數允許你傳入0個或任意個含參數名的參數,這些關鍵字參數在函數內部自動組裝為一個dict。
在這里插入圖片描述
函數person除了必選參數name和age外,還接受關鍵字參數kw。在調用該函數時,可以只傳入必選參數:
在這里插入圖片描述
也可以傳入任意個數的關鍵字參數:
在這里插入圖片描述

命名關鍵字參數
對于關鍵字參數,函數的調用者可以傳入任意不受限制的關鍵字參數。至于到底傳入了哪些,就需要在函數內部通過kw檢查。

仍以person()函數為例,我們希望檢查是否有city和job參數:
廖雪峰Python教程筆記(三)_第22張圖片
但是調用者仍可以傳入不受限制的關鍵字參數:
在這里插入圖片描述

參數組合
在Python中定義函數,可以用必選參數、默認參數、可變參數、關鍵字參數和命名關鍵字參數,這5種參數都可以組合使用。但是請注意,參數定義的順序必須是:必選參數、默認參數、可變參數、命名關鍵字參數和關鍵字參數。

比如定義一個函數,包含上述若干種參數:

廖雪峰Python教程筆記(三)_第23張圖片
廖雪峰Python教程筆記(三)_第24張圖片

函數調用:
在函數內部,可以調用其他函數。如果一個函數在內部調用自身本身,這個函數就是遞歸函數。
計算階乘n! = 1 x 2 x 3 x … x n
在這里插入圖片描述
廖雪峰Python教程筆記(三)_第25張圖片

遞歸函數的優點是定義簡單,邏輯清晰。 理論上,所有的遞歸函數都可以寫成循環的方式,但循環的邏輯不如遞歸清晰。

使用遞歸函數需要注意防止棧溢出。 在計算機中,函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀 。由于棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出??梢栽囋噁act(1000):
RuntimeError: maximum recursion depth exceeded in comparison

解決遞歸調用棧溢出的方法是通過 尾遞歸優化 ,事實上尾遞歸和循環的效果是一樣的,所以,把循環看成是一種特殊的尾遞歸函數也是可以的。

上面的fact(n)函數由于return n * fact(n - 1)引入了乘法表達式,所以就不是尾遞歸了。要改成尾遞歸方式,需要多一點代碼,主要是要把每一步的乘積傳入到遞歸函數中:
廖雪峰Python教程筆記(三)_第26張圖片
fact(5)對應的fact_iter(5, 1)的調用如下:
廖雪峰Python教程筆記(三)_第27張圖片

小結

使用遞歸函數的優點是邏輯簡單清晰,缺點是過深的調用會導致棧溢出。
針對尾遞歸優化的語言可以通過尾遞歸防止棧溢出。尾遞歸事實上和循環是等價的,沒有循環語句的編程語言只能通過尾遞歸實現循環。
Python標準的解釋器沒有針對尾遞歸做優化,任何遞歸函數都存在棧溢出的問題。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲一级视频在线观看 | 欧美综合区 | 999国产视频 | 色噜噜视频| 影音av | 亚洲精品久久久久一区二区三区 | 亚洲 欧洲 偷拍 校园 另类 | 色开心婷婷 | 日韩在线视频在线观看 | 欧美成人欧美激情欧美风情 | 国产在线视频网 | 欧美一区精品 | 国产精品拍拍拍福利在线观看 | 草草影院国产第一页 | 亚洲一区免费看 | 夜精品A片观看无码一区二区 | 伊人精品国产 | 爱福利视频导航 | 欧美成人网在线综合视频 | 97国产精品人妻无码久久久 | 日韩乱轮| 九九黄色 | 自拍偷拍av| 欧美free性 | 成年人xxxx| 天天操网 | 一级毛片一级毛片一级毛片一级毛片 | 国产人成| 亚洲一本| 91短视频免费版 | 最新av在线网址 | 久草资源网站 | 成人午夜免费剧场 | 精品久久久久久久人人人人传媒 | 色综合激情 | 91精品久久久久久久久久 | 小蝌蚪污视频 | 亚洲成人动漫在线观看 | www.91成人| 日韩不卡免费视频 | 国产精品爱久久久久久久 |