Python 閉包及裝飾器

2022-08-21 12:03:13 字數 2572 閱讀 9152

閉包是指延伸了作用域的函式。

自由變數(free variable) 指未在本地作用域中繫結的變數 

函式裝飾器用於在原始碼中標記函式, 以某種方式增強函式的行為。

裝飾器實質,把被裝飾的函式替換為新函式, 二者接收相同的引數,繫結了被裝飾函式最為自由變數,返回被裝飾函式本該返回的值,同時還會做些額外操作

裝飾器的乙個特性就是他們在被裝飾的函式定義之後立即執行

實現乙個簡單的裝飾器:

def decorate(func):

def inner(*args, **kwargs):

print("我是裝飾器")

func(*args, **kwargs)

return inner

@decorate # 相當於 func = decorator(func(*args, **kwargs)) = inner(*args, **kwargs) 同時繫結了被裝飾函式的引用作為自由變數

def func(*args, **kwargs):

pass

@decorate

class test(*args, **kwargs): # 相當於 test = decorate(test(*args, **kwargs)) = inner(*args, **kwargs) 同時繫結了被裝飾函式的引用作為自由變數

pass

print(func.__code__.co_freevars) # 檢視自由變數

print(func.__code__.co_varnames) # 檢視區域性變數

疊加裝飾器:

def decorate1(func):

def inner1(*args, **kwargs):

print("裝飾器1開始裝飾")

func(*args, **kwargs)

print("裝飾器1裝飾結束")

return inner1

def decorate2(func):

def inner2(*args, **kwargs):

print("裝飾器2開始裝飾")

func(*args, **kwargs)

print("裝飾器2裝飾結束")

return inner2

@decorate1 # 相當於 func = decorate1(decorate2(func(*args, **kwargs))) = inner1(inner2)同時繫結了被裝飾函式的引用作為自由變數

@decorate2

def func(*args, **kwargs):

pass

引數化裝飾器:

建立乙個裝飾器工廠函式,將引數傳給它,返回乙個裝飾器, 再應用到被裝飾的函式上

def register(active=true):

def decorate(func):

def inner(*args, **kwargs):

print('before')

func(*args, **kwargs)

if active:

print('another operation')

print('after')

return inner

return decorate

@register(true) # 相當於 func = decorate(func(*args, **kwargs)) = inner(*args, **args) 同時繫結了引數active以及被裝飾函式的引用作為自由變數

def func(a=1):

print(a)

print(func.__code__.co_freevars)

類實現裝飾器  

class decorator:

def __init__(self, func):

self._func = func

def __call__(self, *args, **kwargs):

print('__call__')

self._func(*args, **kwargs)

@decorator

def func(*args, **kwargs): # func = decorator(func(*args, **kwargs)) = obj 同時繫結了被裝飾函式的引用作為例項

pass

func()

引數化類裝飾器 : 類作為裝飾器工廠, 例項為裝飾器, 引數儲存再例項中,將例項作為裝飾器應用到被裝飾函式上

class decorator:

def __init__(self, active):

self._active = active

def __call__(self, func):

if self._active:

print("another operation")

func(*args, **kwargs)

@decorator(active=true)

pass

func()

Python閉包及裝飾器

先看乙個例子 def outer x definner y return x y return innder add outer 8 print add 6 我們定義了乙個方法outer,方法內部又定義了乙個方法inner,方法outer返回值為內部定義的方法inner。同時,內部方法innder使...

Python 裝飾器 ,閉包

1 裝飾器 不改變被裝飾的函式情況下附加一些功能 本質是函式,用於裝飾其他函式,附加一些本身所沒有的功能 實質 是乙個函式 引數 是你要裝飾的函式名 並非函式呼叫 返回 是裝飾完的函式名 也非函式呼叫 作用 為已經存在的物件新增額外的功能 特點 不需要對物件做任何的 上的變動 例1 計算執行時長 i...

Python3 閉包及裝飾器

一.什麼是閉包 不同程式語言實現閉包的方式是不同的,python中閉包從表現形式上看,如果在乙個內部函式裡,對在外部作用域 但不是在全域性作用域 的變數進行引用,那麼內部函式就被認為是閉包 closure 舉個例子 def outer x def inner y return x y return ...