函數嵌套、做用域、閉包

函數總結

# 函數的定義:
def func(a, b):
    print(a, b)
    return a + b


# 函數四個組成部分
# 函數名:調用函數的依據,必須的
# 函數體:執行函數邏輯的,必須的
# 參數列表:爲函數內部提供資源,非必須的
# 返回值:將函數執行結果返回給外界,(非必須的)

# 返回值:空返回(沒有return|空return) | 一值返回  | 多值返回:裝有多個值的元組

# 參數列表:
# 實參:外界調用函數傳入的參數,擁有實際值
# 形參:函數定義時,()中定義用來接受實參的值

# 參數重點一:形參是對實參的值拷貝 *****
ls = [1, 2, 3, 4, 5]
num = 10


def fn(arg, n):
    arg[2] = 300
    print('1:', arg[2])
    print(id(n))
    n = 100
    print(id(n))


fn(ls, num)
# arg是對ls的值拷貝
print('2:', ls[2])
print(id(num))


# 實參的分類
# 位置實參:按位置對應傳遞參數,必須出如今關鍵字實參以前
# 關鍵字實參:不須要按位置對應傳參,用參數名標註爲誰傳參,必須出如今位置實參以後

# 參數重點二:先位置實參後關鍵字實參傳參

# 參數重點三:
# 位置實參:只能給位置形參傳參(位置形參|默認形參|可變長位置形參)
# 關鍵字實參:能夠給任意形參傳參

# 出現順序
# 參數重點四:
# 位置形參 > 默認形參 > 可變長位置形參 > 關鍵字形參 > 可變長關鍵字形參

def fn1(a, b, c=10, *args, d, e=20, f, **kwargs):
    pass

函數對象

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

# 函數對象的應用
# 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,
    'quyu': quyu,
}
# 根據指令獲取計算方法
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)
# global關鍵詞能夠將Local的名字提高爲Global的名字
# 一個文件中的Global名字就是一個,因此函數內部外部使用的名字都是一個
fn()  # 注:必定要調用函數,才能產生名字,並提高
print(num)

函數的嵌套定義

# 將函數直接定義到另外一個函數內部,就可使用外部函數的中的名字
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)  # 30, inner -> outer -> global -> built-in
    inner()
    print('2:', len)  # 20, outer -> global -> built-in
outer()
print('3:', len)  # 10, global -> built-in

del len
print('4:', len)  # len地址, built-in

閉包

# 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()
相關文章
相關標籤/搜索