基石爲勤能補拙的迷宮之旅——第十一天(Python函數對象、名稱空間、函數嵌套、作用域和閉包)

一、函數對象

    函數名就是存放了函數的內存地址,存放了內存地址的變量都是對象,即 函數名 就是 函數對象。

函數對象的應用

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()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章