python基礎(八):函數
函數就是將一些語句集合在一起的部件,他們能夠不止一次的程序中運行,函數還能夠計算出一個返回值,並能夠改變作為函數輸入的參數。而這些參數在代碼運行時每次都不同。以函數的形式去編寫一個操作可以使它成為一個廣泛的應用工具。
基本格式:
def 函數名: 函數體 return 返回值
定義和調用
定義函數按照前面的基本格式定義函數,調用函數時要使用函數名加括號來調用函數,括號中可以包含一個或多個參數。這些參數將會傳遞給函數頭部的參數名。
#定義 def test(x,y): return x*y #調用 test(5,10)
函數參數
必備參數
func(valule) 函數調用時會通過位置來匹配,調用函數時參數不能省略。
默認參數(關鍵字參數)
func(name=value) 函數如果在調用的時候不給參數,就按默認參數的值進行傳遞,如果在調用函數時給默認參數重新賦值則原值會被覆蓋,
def func(name="Joe"): print(name) func() >>>Joe func("AustinJoe") #func(name="AustinJoe")也是可以的 >>>AustinJoe
不定長參數
- func(*args) 將所有位置相關的參數收集到一個新的元組之中,並將這個元組值賦值給變量args。*可以匹配任意長度和數目的參數。
def func(*args):print(args) func(*(1,2,3,4))#func(1,2,3,4)這種形式也是可以的 >>>(1, 2, 3, 4) func([1,2,3],‘hello‘,‘python‘) >>>([1, 2, 3], ‘hello‘, ‘python‘)
2.func(**kwargs)與上面類似,但是是將參數收集到字典中。
def func(**kwargs): print(kwargs) func(a=1,b=2) >>>{‘b‘: 2, ‘a‘: 1}
func(**{‘a‘:1,‘b‘:2})
>>>{‘a‘: 1, ‘b‘: 2}
解包參數
在python中我們可以用*和**對參數解包。
def func(a,b,c,d): print(a,b,c,d) args=(1,2,3,4) func(*args) >>>1 2 3 4
def func(a,b,c,d): print(a,b,c,d) args={‘o‘:1,‘b‘:2,‘c‘:3,‘d‘:4} func(**args) >>>1 2 3 4
註意
參數類型是可以混合使用的,但必須遵循以下法則:
- 在函數調用中,參數必須以此順序出現:位置參數,後面跟著任何關鍵字參數,然後是*args,最後跟著**kwargs。
- 在函數頭部,參數必須以此順序出現:一般參數後面緊跟著默認參數,如果有的話後面是*args,最後是**kwargs。
匿名函數:lambda
lambda是一個表達式,表達式創建了一個之後能夠調用的函數,但是他返回了一個函數而不是將這個函數賦值給變量名。
其一般格式為:
lambda:argument1,argument2··· argumentN :expression using arguments
f = lambda x, y, z: x + y + z print(f(2, 3, 4)) >>>9
lambda表達式常常與map()和filter()函數結合使用,我們接下來就學習這兩個函數。
map():在序列中映射
map函數會對一個序列對象中的每個元素應用被傳入的函數,並且返回了包含所用函數調用結果的一個列表。
l=list(map((lambda x:x+2),[1,2,3,4])) print(l)
>>>[3, 4, 5, 6]
l=list(map(pow,[1,2,3],[5,6,7])) print(l) >>>[1, 64, 2187]
filter():過濾元素
filter()函數會根據測試函數過濾出一些元素。
l=list(filter((lambda x:x>0),range(-10,10))) print(l) >>>[1, 2, 3, 4, 5, 6, 7, 8, 9]
reduce()
reduce()函y數會對每一個元素應用函數並運行到最後結果。
from functools import reduce result=reduce((lambda x,y:x+y),[1,2,3,4]) print(result) >>>10
閉包:函數嵌套(間接函數調用)
閉包是指函數外面調用函數裏面的的函數,即函數嵌套。
def main(): print("hello world") def nest(): print("我是嵌套的函數!") return nest # 第一種形式 main()() >>>hello world >>>我是嵌套的函數! # 第二種形式 m=main() m() >>>hello world >>>我是嵌套的函數!
遞歸函數
遞歸函數的使用要註意:
- 遞歸的次數在python中是有限制的;
- 遞歸函數使用時占用的內存成幾何量增長;
- 遞歸函數要有終止條件。
# 對一個列表求和 def sumtree(L): tot = 0 for x in L: if not isinstance(x, list): tot += x else: tot += sumtree(x) return tot L = [1, [1, 2, [6, 7], 3], 4, 5, [9, 8]] print(sumtree(L)) >>>46
回調函數
函數A的執行取決於函數B中某一條件的執行,則函數A為回調函數。
def main(x): if x>5: print("回調函數未執行!!") else: return callback() def callback(): print("回調函數執行!!") main(10) >>>回調函數未執行!! main(4) >>>回調函數執行!!
作用域
作用域法則:
- 內嵌的模塊是全局作用域;
- 全局作用域的範圍僅限於單個文件;
- 每次對函數的調用都創建了一個本地作用域;
- 賦值的變量名除非聲明為全局變量和非本地變量,否則均為本地變量;
- 所有其他的變量名都可以歸納為本地,全局或者內置的。
X=88 def func(Y): Z=X+Y return Z print(func(12)) # 其中X和函數func都是全局變量名,而Y和Z均為本地變量名
global語句
global 語句用來聲明一個全局或多個全局變量名。
X = 88 def func(): global X X = 99 func() print(X) >> > 99
nonlocal語句
在聲明nonlocal變量名時,該變量名必須存在函數的嵌套的作用域,即他們只能存在於一個嵌套的函數中,並且不能有一個嵌套的def中的第一次賦值創建。
def tester(start): state = start def nested(label): nonlocal state print(label, state) state += 1 return nested f = tester(0) print(f(‘first‘)) >>>first 0 print(f(‘second‘)) >>>second 1 print(f(‘third‘)) >>>third 2
python基礎(八):函數