Python 閉包和裝飾器學習
阿新 • • 發佈:2018-12-25
裝飾器
def out_func(func):
"""
functools.wraps 可以將原函式物件的指定屬性複製個包裝函式物件
"""
@functools.wraps(func)
def inner_func(func, *args, **kwargs):
return func()
return inner_func
@out_func
def foo():
print("hello,world")
裝飾器概念
在不違反開放封閉的原則下,對被裝飾的函式進行功能擴充
實質:閉包
帶來的問題:被裝飾函式名稱等屬性變為閉包的內函式,使用 functools.wraps 可以將原函式物件的指定屬性複製個包裝函式物件
Flask 中 g 變數貫穿當前的這次請求
面試中問到裝飾器的時候:
- 先回答概念:不違反開放封閉原則下,對被裝飾的函式進行功能擴充
- 聊到閉包,說出閉包中的概念和形式
- 說道專案中的實際使用:在 Flask 中 user 物件用到的地方很多,就單獨寫出來為一個裝飾器,將 user 物件查詢出來,放到 g 變數中
- 在 Flask 中,每個 url 物件一個函式,但是被裝飾完,引用指向就變了,使用 functools.wraps 將引用指向原來的指向
閉包:
閉‘包在程式碼中的表現形’式
- 函式巢狀
- 內函式使用了外函式的區域性變數
- 外函式返回的內函式的引用
內函式的引用和外函式被使用的區域性變數構成的特殊空間——閉包
閉包的延遲繫結,當外函式準備返回內函式的引用的時候,發現內函式使用了外函式的區域性變數,就將內函式引用和區域性變數繫結形成特定空間,這種繫結稱為延時繫結
def multipliers():
return [lambda x : i*x for i in range(4)]
print([m(2) for m in multipliers()])
# 上面的程式碼和下面的一樣
def multipliers ():
list_funcs = []
for i in range(4):
def inner(x):
return i * x
list_funcs.append(inner)
return list_funcs
print([m(2) for m in multipliers()])