python基礎 閉包 裝飾器

2021-10-03 06:31:26 字數 4312 閱讀 8780

閉包

定義:乙個函式中再定義乙個函式,其中裡邊的函式用到了外邊函式的變數,則稱這兩個函式為乙個閉包。

看乙個閉包的例子:

def

f1(x)

:deff2(

):return x+

1return f2

ret = f1(10)

print

(ret())

輸出:11

上述**中,呼叫f1函式返回的f2函式的引用,即ret指向的是f2的引用,在呼叫ret時即是呼叫f2函式。

由於閉包引用了外部函式的區域性變數,因此外部函式的區域性變數不能及時釋放,消耗記憶體。

裝飾器在不修改原來**的前提下增加邏輯即可以用到裝飾器。

先來看一下裝飾器的功能:

1.引⼊⽇志

2.函式執⾏時間統計

3.執⾏函式前預備處理

4.執⾏函式後清理功能

5.許可權校驗等場景

6.快取

舉個例子:

無引數裝飾器:

def

func1

(func)

:def

func2()

:print

("add test logic"

)return func(

)return func2

@func1

defwork_platform()

:print

("this is work_platform"

)work_platform(

)輸出:

add test logic

this is work_platform

解釋一下執行原理:

首先,python直譯器從上向下執行**,func1函式載入到記憶體中,在執行@func1時python直譯器中會執行以下邏輯,將@func1下邊的函式名作為func1引數,然後呼叫func1函式,即func1(work_platform),執行func1函式返回func2的引用,並且將返回值再次賦值給@func1下的函式名,即此時的work_platform指向的時func2函式,這樣在呼叫work_platform時實際上是呼叫的func2,如果還不明白的話就以**注釋的形式再敘述一遍

def

func1

(func)

:# python直譯器遇到函式不執行,載入到快取中

deffunc2()

:print

("add test logic"

)return func(

)return func2

# 執行到@func1的時候會將work_platform函式名作為引數傳給func1,呼叫func1,即func1(work_platform)

# 呼叫func1函式後返回func2的引用,並將其賦值給work_platform,這樣work_platform這個函式就會重新指向另外的函式,這樣就會形成以下的形式

# 新work_platform -> def func2():

# print("add test logic")

# work_platform() 這個work_platform是原來指向的函式

# 這樣再次呼叫work_platform函式時,就會呼叫新的work_platform指向的函式,而不是原來定義的那個函式

@func1

defwork_platform()

:print

("this is work_platform"

)work_platform(

)# 這個work_platform指的是新work_platform

這樣一來既增加了驗證邏輯,又執行了原來函式的**

以上這種裝飾器由於被裝飾的函式沒有引數,所以稱為無引數裝飾器

帶引數裝飾器:

def

func1

(func)

:def

func2

(a,b)

:print

("add test logic"

)print

("a:{}"

.format

(a))

print

("b:{}"

.format

(b))

return func(a,b)

return func2

@func1

defwork_platform

(a,b)

:print

("this is work_platform"

)print

(a+b)

work_platform(1,

2)輸出:add test logica:1

b:2this is work_platform

3

由於work_platform 函式指向的是func2,所以所帶的引數也相應的傳給func2

通用裝飾器:即不論被裝飾的函式中存在幾個引數,裝飾器都可以接受而不報錯,所以在func2中使用不定長引數即可。

def

func1

(func)

:def

func2

(*args,

**kwargs)

:print

("add test logic"

)return func(

*args,

**kwargs)

return func2

@func1

defwork_platform

(a,b)

:print

("this is work_platform"

)print

(a+b)

work_platform(1,

2)

給裝飾器加引數,即是在裝飾器的外邊再加一層函式,即在原有裝飾器的基礎上設定外部變數
def

xiaogu

(auth)

:def

func1

(func)

:def

func2

(*args,

**kwargs)

:if auth ==

"root"

:print

("auth is big"

)elif auth ==

"user"

:print

("auth is small"

)print

("add test logic"

)return func(

*args,

**kwargs)

return func2

return func1

@xiaogu(

"root"

)def

work_platform

(a,b)

:print

("this is work_platform"

)print

(a+b)

work_platform(1,

2)

乙個函式有多個裝飾器的情況:裝飾器會自上而下依次執行
def

func1

(func)

:def

func2

(*args,

**kwargs)

:print

("add test logic"

)return func(

*args,

**kwargs)

return func2

defdemo

(func)

:def

func3

(*args,

**kwargs)

:print

("demo func3"

)return func(

*args,

**kwargs)

return func3

@func1

@demo

defwork_platform

(a, b)

:# 先執行func1裝飾器,再執行demo裝飾器,最後執行work_platform函式

print

("this is work_platform"

)print

(a + b)

輸出:add test logic

demo func3

this is work_platform

3

python基礎 閉包 裝飾器

相信大家在學python基礎 江狗 django 的時候都遇到過閉包和裝飾器的知識,但是可能功力不夠好像用的不多。但是作為乙個基礎概念,我們還是要把他學紮實點。所以今天就來將閉包和裝飾器,順便理一下資料傳輸的流程。接下來的流程就是閉包 閉包的資料流程 裝飾器 裝飾器的資料流程 二者關係 實際使用場景...

Python閉包 裝飾器

閉包 legb法則 所謂閉包,就是將組成函式的語句和這些語句的執行環境打包一起時得到的物件 閉包最重要的價值在於封裝上下文環境 下面有個列子來解釋下閉包 列 deffunx x print 開始 deffuny y returnx y print 結束 returnfuny x funx 4 pri...

python 閉包 裝飾器

2.閉包格式 return bar 返回內嵌函式 in test print in 3.使用原理 4.總結 二 裝飾器 2.格式 return test in 閉包函式返回內嵌函式 test aa test aa 裝飾 def aa 這兒如果有引數,test in也必須有一樣的引數,test in中...