python常用函數(shù)詳解
1.函數(shù)的介紹
為什么要有函數(shù)?因為在平時寫代碼時,如果沒有函數(shù)的話,那么將會出現(xiàn)很多重復(fù)的代碼,這樣代碼重用率就比較低。。。并且這樣的代碼維護(hù)起來也是很有難度的,為了解決這些問題,就出現(xiàn)了函數(shù),用來將一些經(jīng)常出現(xiàn)的代碼進(jìn)行封裝,這樣就可以在任何需要調(diào)用這段代碼的地方調(diào)用這個函數(shù)就行了。
函數(shù)的定義:函數(shù)是指將一組語句的集合通過一個名字(函數(shù)名)封裝起來,要想執(zhí)行這個函數(shù),只需調(diào)用其函數(shù)名即可
特性:
代碼重用
保持一致性
可擴(kuò)展性
2.函數(shù)的創(chuàng)建
在python中函數(shù)定義的格式如下:
def 函數(shù)名(形參): 函數(shù)體內(nèi)部代碼塊
函數(shù)的調(diào)用使用 函數(shù)名(實參) 就可以調(diào)用函數(shù)了。
函數(shù)名的命名規(guī)則和變量的命名規(guī)則一樣:
- 函數(shù)名必須以下劃線或字母開頭,可以包含任意字母、數(shù)字或下劃線的組合。不能使用任何的標(biāo)點(diǎn)符號;
- 函數(shù)名是區(qū)分大小寫的。
- 函數(shù)名不能是保留字。
形參和實參的區(qū)別:
函數(shù)在定義的時候,函數(shù)名后面的括號中可以添加參數(shù),這些參數(shù)就叫做形參,形參:顧名思義就是形式參數(shù),只是一個代號。
實參是在調(diào)用函數(shù)的時候函數(shù)名后面的括號中的參數(shù),形參和實參需要一一對應(yīng)起來,否則調(diào)用函數(shù)會報錯。
3.函數(shù)參數(shù)及返回值
前面提到函數(shù)的形參和實參要一一對應(yīng),那么參數(shù)對應(yīng)有如下幾種:
- 必須參數(shù)
- 關(guān)鍵字參數(shù)
- 默認(rèn)參數(shù)
- 不定長參數(shù) *args
- 不定長參數(shù) **kwargs
1.必須參數(shù):
必須參數(shù)必須以對應(yīng)的關(guān)系一個一個傳遞進(jìn)入函數(shù),函數(shù)調(diào)用時傳遞的實參必須和函數(shù)定義時的形參一一對應(yīng),不能多也不能少,順序也得一致。
舉個栗子:
def f(name,age): print(name,age) f("小明",18)
2.關(guān)鍵字參數(shù)
關(guān)鍵字參數(shù)是實參里面的概念,在調(diào)用函數(shù)的時候聲明某個參數(shù)是屬于某個關(guān)鍵字的。使用關(guān)鍵字參數(shù)允許函數(shù)調(diào)用時參數(shù)的順序與聲明時不一致,因為 Python 解釋器能夠用參數(shù)名匹配參數(shù)值。
舉個栗子:
def f(name,age): print(name,age) f(name="小明",18)
3.默認(rèn)參數(shù)
默認(rèn)參數(shù)是在函數(shù)聲明的時候,可以給某個參數(shù)指定默認(rèn)值,這樣的參數(shù)叫做默認(rèn)值參數(shù)。如果在調(diào)用函數(shù)的時候,默認(rèn)參數(shù)沒有接收到對應(yīng)的實參,那么就會將默認(rèn)值賦值給這個參數(shù)。
舉個栗子:
def f(name,age,sex="male"): print(name,age,sex) f(name="小明",18)
這樣,就會把默認(rèn)參數(shù)male賦值給sex了。
4.不定長參數(shù) *args
在python里面,函數(shù)在聲明的時候,參數(shù)中可以使用(*變量名)的方式來接受不確定長度的參數(shù),但是在python里面大家約定俗成使用*args接受不定長參數(shù),這樣在調(diào)用函數(shù)的時候傳遞的參數(shù)就可以是不定長度的了。args接受了不定長參數(shù)之后,將這些參數(shù)放到一個tuple里面,可以通過訪問args來獲取這些不定長參數(shù)。
舉個栗子:
def f(*args): print(args) f("小明",18,"male")
打印出來的是一個tuple,里面存放了(“小明”,18,”male”)這三個元素。
5.不定長參數(shù) **kwargs
但是上面的args只能接收未命名的參數(shù),那假如有類似于關(guān)鍵字參數(shù)的不定長參數(shù)該怎么辦呢?python里面使用(**變量名)來接收不定長的命名變量參數(shù)。同樣,python里面也約定俗成使用**kwargs接收不定長命名參數(shù)。kwargs接收了不定長參數(shù)之后,將這些參數(shù)放到一個字典里面,可以通過key獲取到相應(yīng)的參數(shù)值。
舉個栗子:
def f(**kwargs): print(kwargs) f(name="小明",age=18,sex="male")
介紹完了這些參數(shù)之后,接下來要介紹的是關(guān)于這些參數(shù)混合使用的情況:
假如一個函數(shù)使用了上面所有種類的參數(shù),那該怎么辦?為了不產(chǎn)生歧義,python里面規(guī)定了假如有多種參數(shù)混合的情況下,遵循如下的順序使用規(guī)則:
def f(必須參數(shù),默認(rèn)參數(shù),*args,**kwargs):
pass
如果同時存在args和kwargs的話,args在左邊
默認(rèn)參數(shù)在必須參數(shù)的右邊,在*args的左邊
關(guān)鍵字參數(shù)的位置不固定(ps:關(guān)鍵字參數(shù)也不在函數(shù)定義的時候確定)
那么,假如有一個列表想要傳遞進(jìn)入一個不定長的未命名參數(shù)的函數(shù)中去,可以在該列表前面加上*實現(xiàn),同理如果想傳遞一個字典進(jìn)入不定長命名參數(shù)的函數(shù)中去,可以在該字典前面加上**
舉個栗子:
def f(*args,**kwargs): print(args) for i in kwargs: print("%s:%s"%(i,kwargs[i])) f(*[1,2,3],**{"a":1,"b":2})
函數(shù)的返回值
要想獲取函數(shù)的執(zhí)行結(jié)果,就可以用return語句把結(jié)果返回
注意:
函數(shù)在執(zhí)行過程中只要遇到return語句,就會停止執(zhí)行并返回結(jié)果,也可以理解為 return 語句代表著函數(shù)的結(jié)束 如果未在函數(shù)中指定return,那這個函數(shù)的返回值為None
return多個對象,解釋器會把這多個對象組裝成一個元組作為一個一個整體結(jié)果輸出。
4.LEGB作用域
python中的作用域分4種情況:
L:local,局部作用域,即函數(shù)中定義的變量;
E:enclosing,嵌套的父級函數(shù)的局部作用域,即包含此函數(shù)的上級函數(shù)的局部作用域,但不是全局的;
G:globa,全局變量,就是模塊級別定義的變量;
B:built-in,系統(tǒng)固定模塊里面的變量,比如int, bytearray等。 搜索變量的優(yōu)先級順序依次是:作用域局部>外層作用域>當(dāng)前模塊中的全局>python內(nèi)置作用域,也就是LEGB。
local和enclosing是相對的,enclosing變量相對上層來說也是local。
在Python中,只有模塊(module),類(class)以及函數(shù)(def、lambda)才會引入新的作用域,其它的代碼塊(如if、try、for等)不會引入新的作用域。
變量的修改(錯誤修改,面試題里經(jīng)常出):
x=6 def f2(): print(x) x=5 f2() # 錯誤的原因在于print(x)時,解釋器會在局部作用域找,會找到x=5(函數(shù)已經(jīng)加載到內(nèi)存),但x使用在聲明前了,所以報錯: # local variable 'x' referenced before assignment.如何證明找到了x=5呢?簡單:注釋掉x=5,x=6 # 報錯為:name 'x' is not defined #同理 x=6 def f2(): x+=1 #local variable 'x' referenced before assignment. f2()
global關(guān)鍵字
當(dāng)內(nèi)部作用域想修改外部作用域的變量時,就要用到global和nonlocal關(guān)鍵字了,當(dāng)修改的變量是在全局作用域(global作用域)上的,就要使用global先聲明一下,代碼如下:
count = 10 def outer(): global count print(count) count = 100 print(count) outer()
nonlocal關(guān)鍵字
global關(guān)鍵字聲明的變量必須在全局作用域上,不能嵌套作用域上,當(dāng)要修改嵌套作用域(enclosing作用域,外層非全局作用域)中的變量怎么辦呢,這時就需要nonlocal關(guān)鍵字了
def outer(): count = 10 def inner(): nonlocal count count = 20 print(count) inner() print(count) outer()
小結(jié)
- 變量查找順序:LEGB,作用域局部>外層作用域>當(dāng)前模塊中的全局>python內(nèi)置作用域;
- 只有模塊、類、及函數(shù)才能引入新作用域;
- 對于一個變量,內(nèi)部作用域先聲明就會覆蓋外部變量,不聲明直接使用,就會使用外部作用域的變量;
- 內(nèi)部作用域要修改外部作用域變量的值時,全局變量要使用global關(guān)鍵字,嵌套作用域變量要使用nonlocal關(guān)鍵字。nonlocal是python3新增的關(guān)鍵字,有了這個 關(guān)鍵字,就能完美的實現(xiàn)閉包了。
5.特殊函數(shù)
遞歸函數(shù)定義:遞歸函數(shù)就是在函數(shù)內(nèi)部調(diào)用自己
有時候解決某些問題的時候,邏輯比較復(fù)雜,這時候可以考慮使用遞歸,因為使用遞歸函數(shù)的話,邏輯比較清晰,可以解決一些比較復(fù)雜的問題。但是遞歸函數(shù)存在一個問題就是假如遞歸調(diào)用自己的次數(shù)比較多的話,將會使得計算速度變得很慢,而且在python中默認(rèn)的遞歸調(diào)用深度是1000層,超過這個層數(shù)將會導(dǎo)致“爆?!薄?。。所以,在可以不用遞歸的時候建議盡量不要使用遞歸。
舉個栗子:
def factorial(n): # 使用循環(huán)實現(xiàn)求和 Sum=1 for i in range(2,n+1): Sum*=i return Sum print(factorial(7)) def recursive_factorial(n): # 使用遞歸實現(xiàn)求和 return (2 if n==2 else n*recursive_factorial(n-1)) print(recursive_factorial(7)) def feibo(n): # 使用遞歸實現(xiàn)菲波那切數(shù)列 if n==0 or n==1:return n else:return feibo(n-1)+feibo(n-2) print(feibo(8)) def feibo2(n): # 使用循環(huán)實現(xiàn)菲波那切數(shù)列 before,after=0,1 for i in range(n): before,after=after,before+after return before print(feibo2(300))
遞歸函數(shù)的優(yōu)點(diǎn):定義簡單,邏輯清晰。理論上,所有的遞歸函數(shù)都可以寫成循環(huán)的方式,但循環(huán)的邏輯不如遞歸清晰。
遞歸特性:
- 必須有一個明確的結(jié)束條件
- 每次進(jìn)入更深一層遞歸時,問題規(guī)模相比上次遞歸都應(yīng)有所減少
- 遞歸效率不高,遞歸層次過多會導(dǎo)致棧溢出(在計算機(jī)中,函數(shù)調(diào)用是通過棧(stack)這種數(shù)據(jù)結(jié)構(gòu)實現(xiàn)的,每當(dāng)進(jìn)入一個函數(shù)調(diào)用,棧就會加一層棧幀,每當(dāng)函數(shù)返 回,棧就會減一層棧幀。由于棧的大小不是無限的,所以,遞歸調(diào)用的次數(shù)過多,會導(dǎo)致棧溢出。)
6.函數(shù)式編程
關(guān)于函數(shù)式編程,我理解的也不是很深,但是python中有4個比較重要的內(nèi)置函數(shù),組合起來使用有時候能大大提高編程效率。
1 filter(function, sequence) str = ['a', 'b','c', 'd'] def fun1(s): if s != 'a': return s ret = filter(fun1, str) print(list(ret))# ret是一個迭代器對象
對sequence中的item依次執(zhí)行function(item),將執(zhí)行結(jié)果為True的item做成一個filter object的迭代器返回??梢钥醋魇沁^濾函數(shù)。
2 map(function, sequence)
str = [1, 2,'a', 'b'] def fun2(s): return s + "alvin" ret = map(fun2, str) print(ret) # map object的迭代器 print(list(ret))# ['aalvin', 'balvin', 'calvin', 'dalvin']
對sequence中的item依次執(zhí)行function(item),將執(zhí)行結(jié)果組成一個map object迭代器返回. map也支持多個sequence,這就要求function也支持相應(yīng)數(shù)量的參數(shù)輸入:
def add(x,y): return x+y print (list(map(add, range(10), range(10))))##[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
3 reduce(function, sequence, starting_value)
from functools import reduce def add1(x,y): return x + y print (reduce(add1, range(1, 101)))## 4950 (注:1+2+...+99) print (reduce(add1, range(1, 101), 20))## 4970 (注:1+2+...+99+20)
對sequence中的item順序迭代調(diào)用function,如果有starting_value,還可以作為初始值調(diào)用.
4 lambda
普通函數(shù)與匿名函數(shù)的對比:
#普通函數(shù) def add(a,b): return a + b print add(2,3) #匿名函數(shù) add = lambda a,b : a + b print add(2,3) #========輸出=========== 5 5
匿名函數(shù)的命名規(guī)則,用lamdba 關(guān)鍵字標(biāo)識,冒號(:)左側(cè)表示函數(shù)接收的參數(shù)(a,b) ,冒號(:)右側(cè)表示函數(shù)的返回值(a+b)。
因為lamdba在創(chuàng)建時不需要命名,所以,叫匿名函數(shù)
- Python3的urllib.parse常用函數(shù)小結(jié)(urlencode,quote,quote_plus,unquote,unquote_plus等)
- Python time模塊詳解(常用函數(shù)實例講解,非常好)
- Python pandas常用函數(shù)詳解
- Python OS模塊常用函數(shù)說明
- Python numpy 常用函數(shù)總結(jié)
- Python正則表達(dá)式常用函數(shù)總結(jié)
- Python學(xué)習(xí)筆記之常用函數(shù)及說明
- Python字符串和文件操作常用函數(shù)分析
- Python中functools模塊的常用函數(shù)解析
- python常用函數(shù)與用法示例
相關(guān)文章
Pycharm搭建Django項目詳細(xì)教程(看完這一篇就夠了)
這篇文章主要給大家介紹了關(guān)于Pycharm搭建Django項目的詳細(xì)教程,想要學(xué)習(xí)的小伙伴看完這一篇就夠了,pycharm是一種Python?IDE,帶有一整套可以幫助用戶在使用Python語言開發(fā)時提高其效率的工具,需要的朋友可以參考下2023-11-11python基礎(chǔ)學(xué)習(xí)之如何對元組各個元素進(jìn)行命名詳解
python的元祖和列表類似,不同之處在于元祖的元素不能修改,下面這篇文章主要給大家介紹了關(guān)于python基礎(chǔ)學(xué)習(xí)之如何對元組各個元素進(jìn)行命名的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-07-07簡要講解Python編程中線程的創(chuàng)建與鎖的使用
這篇文章主要介紹了簡要講解Python編程中線程的創(chuàng)建與鎖的使用,Python中雖然有GIL的存在,但依然是能夠創(chuàng)建多個線程來交替使用的,需要的朋友可以參考下2016-02-02關(guān)于Python核心框架tornado的異步協(xié)程的2種方法詳解
今天小編就為大家分享一篇關(guān)于Python核心框架tornado的異步協(xié)程的2種方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08PyQt5設(shè)置登錄界面及界面美化的實現(xiàn)
這篇文章主要介紹了PyQt5設(shè)置登錄界面及界面美化的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03