1. 程式人生 > 實用技巧 >day12:閉包函式&匿名函式

day12:閉包函式&匿名函式

閉包函式

閉包函式的定義:

如果內函式使用了外函式的區域性變數
並且外函式把內函式返回出來的過程 叫做閉包
裡面的內函式是閉包函式

一個簡單的閉包函式示例:

def songyunjie_family():
father = "王健林"
def f_hobby():
print("這是我爸爸{}".format(father)) # 內函式使用了外函式的區域性變數father
return f_hobby # 外函式把內函式返回出來了

複雜的閉包函式(多層)

def mashengping_family():
father = "馬雲"
jiejie = "馬蓉"
meimei = "馬諾"
money =1000 def jiejie():
nonlocal money
money-=700
print("還剩下{}元".format(money))
def meimei():
nonlocal money
money-=200
print("還剩下{}元".format(money))
def big_master():
return (jiejie,meimei)
return big_master func = mashengping_family()
print(func) # <function mashengping_family.<locals>.big_master at 0x000001F4CB0F5620> # 返回的是元組
tup = func()
print(tup) # (<function mashengping_family.<locals>.jiejie at 0x0000013D5B175158>, <function mashengping_family.<locals>.meimei at 0x0000013D5B175268>) # 獲取姐姐
jiejie = tup[0]
# 獲取妹妹
meimei = tup[1] # big_master 是閉包函式,是直接被mashengping_family返回出來的
# jiejie,meimei 是通過big_master間接被返回到函式外面的 # 呼叫妹妹
meimei() # 還剩下800元
# 呼叫姐姐
jiejie() # 還剩下100元 # 獲取閉包函式所使用的變數 __closure__
res = func.__closure__
print(res) # (<cell at 0x000001AF2B5A76A8: function object at 0x000001AF2B645158>, <cell at 0x000001AF2B5A76D8: function object at 0x000001AF2B645268>) # cell_contents 用來獲取單元格物件當中的閉包函式
jiejie = res[0].cell_contents # <function mashengping_family.<locals>.jiejie at 0x0000019161005158>
meimei = res[1].cell_contents # <function mashengping_family.<locals>.meimei at 0x0000019161005268> i = jiejie.__closure__[0] # <cell at 0x0000020E9B977708: int object at 0x0000000054928CD0>
j = meimei.__closure__[0] # <cell at 0x0000020E9B977708: int object at 0x0000000054928CD0> a = jiejie.__closure__[0].cell_contents #
b = meimei.__closure__[0].cell_contents #

閉包的特徵

內函式使用了外函式的區域性變數
那麼該變數與閉包函式發生繫結
延長該變數的生命週期

def outer(val):
def inner(num):
return val+num
return inner func = outer(10) # func = inner
res = func(15) # res = func(15) =inner(15)
print(res) #
"""
10實參-->val形參
因為內函式inner是閉包函式 使用了外函式val
那麼該變數val生命週期被延長 沒有隨著函式呼叫的結束而釋放
res = inner(15) => return val+num =>10+15 =>25
"""

閉包的意義

閉包的意義:閉包可以優先使用外函式中的變數,並對閉包中的值起到了封裝保護的作用,外部無法訪問

# 模擬滑鼠點選次數
num = 0
def click_num():
global num
num += 1
print(num) click_num() #
click_num() #
click_num() #
num = 100
click_num() #
click_num() # '''
很顯然,這樣是不行的,定義了全域性變數100後,值就從100開始加了.
想一個辦法,讓其就算在中間插入num=100也沒用
''' # 解決方案
def click_num():
num=0
def func():
nonlocal num
num+=1
print(num)
return func func = click_num()
func() #
func() #
num = 1000
func() #
func() #
func() #

匿名函式

匿名函式 : 用一句話來表達只有返回值的函式

語法:lambda 引數 : 返回值

目的:追求程式碼:簡潔,高效

1.無參的lambda 表示式

# 1.無參的lambda 表示式
def func():
return "" # 改寫
func = lambda : ""
res = func()
print(res)

2.有參的lambda 表示式

# 2.有參的lambda 表示式
def func(n):
return type(n) # 改寫
func = lambda n : type(n)
print( func([1,2,3]) )

3.帶有判斷條件的lambda 表示式

def func(n):
if n % 2 == 0:
return "偶數"
else:
return "奇數" func = lambda n : "偶數" if n % 2 == 0 else "奇數"
res = func(17)
print(res)

4.三元運運算元(三目運運算元)

"""
語法:
真值 if 條件表示式 else 假值 如果條件表示式為真,返回真值,否則返回假值
"""
n = 16
res = "偶數" if n % 2 == 0 else "奇數"
print(res)

5.小練習

# 小練習 , 傳遞兩個數, 返回較大的那一個
def func(x,y):
if x>y:
return x
else:
return y func = lambda x,y : x if x>y else y
res = func(200,100)
print(res)