一、函數對象
函數名就是存放了函數的內存地址,存放了內存地址的變量都是對象,即 函數名 就是 函數對象。
函數對象的應用
1 .可以直接被引用——fn = cp_fn
2 .可以當作函數參數傳遞——computed(cp_fn, 100, 20)
3 .可以作爲函數的返回值——get_cp_fn(cmd): return add
4 .可以作爲容器類型的元素——method_map: 對應關係中的值
def add(a, b):
return a + b
def low(a, b):
return a - b
def jump(a, b):
return a * b
def full(a, b):
return a / b
def quyu(a, b):
return a % b
def computed(fn, n1, n2):
res = fn(n1, n2)
return res
method_map = {
'add': add,
'low': low,
'jump': jump,
'full': full,
'mod': mod,
}
# 根據指令獲取計算方法
def get_cp_fn(cmd):
if cmd in method_map:
return method_map[cmd]
return add # 輸入有誤用默認方法處理
while True:
cmd = input('cmd: ')
if cmd == 'quit':
break
cp_fn = get_cp_fn(cmd)
result = computed(cp_fn, 100, 20)
print(result)
二、名稱空間
名稱空間:存放名字與內存空間地址對應關係的容器
作用:解決由於名字有限,導致名字重複發送衝突的問題
三種名稱空間
- Built-in:內置名稱空間;系統級,一個;隨解釋器執行而產生,解釋器停止而銷燬
- Global:全局名稱空間;文件級,多個;隨所屬文件加載而產生,文件運行完畢而銷
- Local:局部名稱空間;函數級,多個;隨所屬函數執行而產生,函數執行完畢而銷燬
注:
del 名字:可以移除查找最近的名字與內存空間地址的對應關係
加載順序:Built-in > Global > Local
global 關鍵詞
def fn()
global num
num = 20
print(num)
fn()
print(num)
global關鍵詞可以將Local的名字提升爲Global的名字
一個文件中的Global名字就是一個,所以函數內部外部使用的名字都是一個
一定要調用函數,才能產生名字,並提升
三、函數的嵌套
定義
將函數直接定義到另一個函數內部,就可以使用外部函數的中的名字
def outer():
num = 20
def inner():
print(num) # inner就可以直接使用outer中的名字
inner()
outer()
四、作用域
作用域:名字起作用的範圍
作用:解決同名字可以共存問題
四種作用域
- Built-in:內置作用域,所有文件所有函數
- Global:全局作用域,當前文件所有函數
- Enclosing:嵌套作用域,當前函數與當前函數的內部函數
- Local:局部作用域,當前函數
不同作用域之間名字不衝突,以達到名字的重用
查找順序:Local > Enclosing > Global > Built-in
len = 10
def outer():
len = 20 # 外層函數的局部變量:Enclosing - 嵌套作用域
def inner():
len = 30
print('1:', len) # inner -> outer -> global -> built-in
inner()
print('2:', len) # outer -> global -> built-in
outer()
print('3:', len) # global -> built-in
del len
print('4:', len) # built-in
五、閉包
閉包就是函數嵌套(格式稍作改良)。
inner可以使用outer的局部變量:可以將inner定義在outer中
inner的調用還是在外部:inner函數對象能被outer返回
將內部函數對象作爲外部函數的返回值:1.可以使用局部變量; 2.不改變函數的調用位置
def outer():
num = 10
def inner(): # 閉包:定義在函數內部的函數稱之爲閉包
print(num)
return inner
fn = outer() # fn = inner
fn()
closure:被包裹的函數,稱之爲閉包
完整的閉包結構:1.將函數進行閉包處理;2.提升函數名的作用域,將內部函數對象作爲外部函數的返回值
def outer(url):
def get_html():
html = requests.get(url)
print(html.text)
return get_html
# 先預定義多個爬蟲方法,爬頁面操作並未執行
baidu = outer('https://www.baidu.com')
python = outer('https://www.python.org')
sina = outer('https://www.sina.com.cn')
# 什麼時候想爬什麼頁面就調用指定頁面的爬蟲方法
baidu()
sina()
baidu()