1. 程式人生 > >Python 閉包和裝飾器學習

Python 閉包和裝飾器學習

裝飾器

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 變數貫穿當前的這次請求

面試中問到裝飾器的時候:

  1. 先回答概念:不違反開放封閉原則下,對被裝飾的函式進行功能擴充
  2. 聊到閉包,說出閉包中的概念和形式
  3. 說道專案中的實際使用:在 Flask 中 user 物件用到的地方很多,就單獨寫出來為一個裝飾器,將 user 物件查詢出來,放到 g 變數中
  4. 在 Flask 中,每個 url 物件一個函式,但是被裝飾完,引用指向就變了,使用 functools.wraps 將引用指向原來的指向

閉包:

閉‘包在程式碼中的表現形’式

  1. 函式巢狀
  2. 內函式使用了外函式的區域性變數
  3. 外函式返回的內函式的引用

內函式的引用和外函式被使用的區域性變數構成的特殊空間——閉包

閉包的延遲繫結,當外函式準備返回內函式的引用的時候,發現內函式使用了外函式的區域性變數,就將內函式引用和區域性變數繫結形成特定空間,這種繫結稱為延時繫結

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()])