四、函數
一、函數體系知識
1 什麽是函數?
2 為什麽要用函數?
3 函數的分類:內置函數與自定義函數
4 如何自定義函數
語法
定義有參數函數,及有參函數的應用場景
定義無參數函數,及無參函數的應用場景
定義空函數,及空函數的應用場景
5 調用函數
如何調用函數
函數的返回值
函數參數的應用:形參和實參,位置參數,關鍵字參數,默認參數,*args,**kwargs
6 高階函數(函數對象)
7 函數嵌套
8 作用域與名稱空間
9 裝飾器
10 叠代器與生成器及協程函數
11 三元運算,列表解析、生成器表達式
12 函數的遞歸調用
13 內置函數
14 面向過程編程與函數式編程
二、函數基礎
1. 為什麽要有函數?什麽是函數?
1)組織結構不清晰,可讀性差;
2)代碼冗余;
3)管理維護難度極大,擴展性差;
具備某一功能的工具就是程序中的函數;
事先準備工具的過程,即函數的定義;
拿來就用,即函數的調用;
所以函數的使用必須遵循,先定義,再調用。
2. 函數定義:
語法:
def 函數名(參數1,參數2, 參數3,...):
‘‘‘
文檔描述
‘‘‘
return
def: 關鍵字
函數名:用來調用函數(函數名的命名,必須能夠反映出函數的功能)
文檔描述:推薦寫,來增強函數的可讀性
return: 函數的返回值
函數名(): 小括號調用函數
函數調用的過程:
a. 先找到內存中函數名對應的值(函數體);
b. 通過小括號來引用這個函數體,同時會傳入函數需要的參數;
c. 執行函數體的代碼;
1)定義函數的三種類型
a. 有參函數:
參數是函數體代碼用來接收外部傳入值的;
b. 無參函數:
當函數體的代碼邏輯,不需要函數的調用者傳入值的情況下,就無參;
定義時無參,意味著調用是也不需要傳入參數;
c. 空函數:
函數體為 pass
def func():
pass
3. 函數調用
函數名加括號,即調用函數;
原則:先定義,後調用;沒有定義函數直接調用,就相當於調用一個不存在變量名;
定義階段:只檢測語法,不執行函數代碼;
調用階段:執行函數代碼;
4. 函數返回 return
1) 返回的三種情況:
a. 無return語句,或只寫一個 return關鍵字:
返回 None
b. return 一個值:
返回該值
c. return 多個值:
返回一個元組
2) 函數體內可以有多個return語句,return語句執行之後,函數結束;
5. 形參與實參是什麽?
定義:形參即變量名,實參即變量值。
重點:函數調用時,將值綁定到變量名上,函數調用結束,解除綁定。
例子:
def foo(x, y): # x, y 是形參
pass
foo(10, 11) # 10,11 是實參
1)位置參數: 實參
a. 按照從左到右的順序定義的參數
b. 位置形參:必選參數;
c. 位置實參:按照位置給形參傳值;
2)關鍵字參數:實參
a. 按照key=value的形式定義的實參;
b. 無需按照位置為形參傳值;
c. 註意:
關鍵字實參必須在位置實參右面;
對同一個形參不能重復傳值;
3)默認參數:形參
a. 形參在定義時就已經為其賦值
b. 可以傳值也可以不傳值;
c. 經常需要變得參數定義成位置形參;
d. 變化較小的參數定義成默認參數(形參);
e. 註意:
默認參數只在定義時賦值一次;
默認參數的定義應該在位置形參右面;
默認參數通常應該定義成不可變類型;
4)可變長參數:形參
a. 可變長指的是實參值的個數不固定;
b. 而實參有按位置和按關鍵字兩種形式定義,針對這兩種形式的可變長,形參對應有兩種解決方案來完整地存放它們,分別是*args,**kwargs;
5)命名關鍵字參數: 形參
a. *後定義的參數,必須被傳值(有默認值的除外),且必須按照關鍵字實參的形式傳遞
b. 可以保證,傳入的參數中一定包含某些關鍵字;
三、函數對象、函數嵌套、名稱空間與作用域、裝飾器
(一)函數對象
1. 函數是一類對象,即函數可以當作數據傳遞
1)可以被引用;
2)可以當作參數傳遞;
3)返回值可以是函數;
3)可以當作容器類型的元素;
2. 利用函數對象可傳遞的特性,優雅取代多分支的if
例子:
def foo():
print(‘foo‘)
def bar():
print(‘bar‘)
dic={
‘foo‘:foo,
‘bar‘:bar,
}
while True:
choice=input(‘>>: ‘).strip()
if choice in dic:
dic[choice]()
(二)函數嵌套
1. 函數的嵌套調用
def max(x,y):
return x if x > y else y
def max4(a,b,c,d):
res1=max(a,b)
res2=max(res1,c)
res3=max(res2,d)
return res3
print(max4(1,2,3,4))
2. 函數的嵌套定義
def f1():
def f2():
def f3():
print(‘from f3‘)
f3()
f2()
f1()
f3() # 調用內部函數報錯,不在全局的命名空間
(三)名稱空間與作用域
1. 什麽是名稱空間?
名稱空間:
存放名字的地方,三種名稱空間。
例子:
x = 1,1存放於內存中,那名字x存放在哪裏呢? --> 名稱空間:存放名字 x,和存放 x與1 綁定關系。
2. 名稱空間的加載順序
內置名稱空間 --> 全局名稱空間 --> 局部名稱空間
python test.py
1)python解釋器先啟動,加載內置名稱空間(python解釋器自帶的);
2)執行test.py文件,然後以文件為基礎,加載全局名稱空間;
3)在執行文件的過程中如果調用函數,則臨時產生局部名稱空間;
內置名稱空間:隨著python解釋的啟動而生效,解釋器運行結束失效;
全局名稱空間:文件級別的名字,在運行文件時生效,運行結束結束或運行時被刪除失效;
局部名稱空間:只存在函數內部,只有在函數被調用時臨時生效,調用結束失效;
3. 名字的查找順序
局部名稱空間 ---> 全局名稱空間 ---> 內置名稱空間
註意:在全局無法查看局部的,在局部可以查看全局的
4.作用域
1)作用域即範圍
全局作用域(內置名稱空間與全局名稱空間):全局存活,全局有效;
a. 在任意位置都能訪問到;
b. 該範圍的名字會伴隨程序整個生命周期;
局部作用域(局部名稱空間):臨時存活,局部有效;
a. 只能在函數內使用;
b. 調用函數時生效,調用結束失效;
2)作用域關系是在函數定義階段就已經固定的,與函數的調用位置無關;
5. 關鍵字 global 與 nonlocal
1)關鍵字 global
a. 聲明全局變量,如果在局部要對全局變量修改,需要在局部也要先聲明該全局變量。
b. 在局部如果不聲明全局變量,並且不修改全局變量。則可以正常使用全局變量。
2)關鍵字 nonloccal 用來在函數或其他作用域中使用外層(非全局)變量
用來在函數或其他作用域中使用外層(非全局)變量。
(四)閉包函數
1. 什麽是閉包?
內部函數包含對外部作用域而非全局作用域的引用。
2. 閉包的意義與應用
1)意義:
返回一個包含上層作用域狀態的函數對象,該函數對象無論在何處調用,優先使用自己外層包裹的作用域。
2) 應用領域:
延遲計算(原來我們是傳參,現在我們是包起來)
例子:
from urllib.request import urlopen
def index(url):
def get():
return urlopen(url).read()
return get
baidu=index(‘http://www.baidu.com‘)
print(baidu().decode(‘utf-8‘))
四、函數