Python閉包 裝飾器

2021-08-14 14:44:38 字數 4056 閱讀 6055

閉包&legb法則:

所謂閉包,就是將組成函式的語句和這些語句的執行環境打包一起時得到的物件

閉包最重要的價值在於封裝上下文環境

下面有個列子來解釋下閉包

列:

deffunx(x):

print('-----------開始------------')

deffuny(y):

returnx*y

print('-----------結束-------------')

returnfuny

x=funx(4)

print(x(5))

》-----------開始------------

》-----------結束-------------

》20

我們來分析下**,函式funy封裝在funx中,我們先看這段**x=funx(4),這段**會如何執行呢。
首先,呼叫funx函式,然後將4傳入進去,這裡就是x指向4,是乙個引用,這點要記住,後面裝飾器重點講的就是引用。隨後就是進入funx函式了,執行第乙個輸出語句,編譯器讀到def funy():時,知道這裡是乙個函式的定義,所以編輯器會將這個函式讀到記憶體中,但不會執行函式裡面的語句,因為還沒有變數來呼叫這個函式,然後編譯器執行到第二個輸出語句,所以輸出結果時先輸出這這兩句輸出**,然後編譯器讀取到return funy時,程式結束,因為有return,所以一定要有變數來接收這個返回的值,我們仔細看一下,返回的值是乙個函式,所以我們將這個函式的引用賦給x,所以x和funy是等價的,可以將x函式看做是funy函式,所以我們使用x就是在使用funy函式,funy函式需要乙個引數,然後執行print(x(5)),因為funy函式裡面返回x*y,所以就看到我們輸出的結果了,沒錯,閉包就是這麼簡單。
接下來講裝飾器,什麼叫裝飾器呢,簡單來說就是將程式裡面可有可無或者不是核心**的**剝離出來,精簡**,使**更具可讀性,裝飾器可以做很多事,不會裝飾器的程式設計師就不叫程式設計師,這是乙個很重要的知識點,它不同於繼承,但又類似繼承。下面我們用一段**來講解裝飾器
deffunx(f):

print('-----------開始111111------------')

deffuny():

f()print('函式內111111。。。。')

print('-----------結束111111-------------')

returnfuny

deffx(f):

print('-----------開始222222------------')

deffy():

f()print('函式內222222。。。。')

print('-----------結束222222-------------')

returnfy

@funx

@fxdeftest():

print('test......')

test()

》-----------開始222222------------

》-----------結束222222-------------

》-----------開始111111------------

》-----------結束111111-------------

》test......

》函式內222222。。。。

》函式內111111。。。。

首先先看**,先不看函式定義那部分,先看@funx

@fxdeftest():

print('test......')

這部分,我們按到test函式上面有兩個語句,分別是@funx和@fx,這就是裝飾器的結構,這樣也叫做  語法糖,將它繫結test函式,然後我們看**,這兩個語法糖的作用是將test函式傳入這兩個語法糖中,這裡有兩個語法糖,我們先執行那個呢,我們可以將它看做是衣服,test函式就相當於內衣,而fx語法糖就相當於保暖衣,funx語法糖則相當於外套,我們穿衣服是先穿內衣再穿保暖衣再穿外套吧,這裡就和穿衣服一樣。
前面所有的語句都是定義函式,只有最後一句是呼叫函式,我們呼叫test函式,然後**就會跳到
@funx

@fxdeftest():

print('test......')

這句,我們按穿衣服的順序來看,這句**就相當於funx(fx(test())),相當於函式的一層層巢狀,也就是剛才所說的穿衣服一樣,
1.將test()函式穿入fx函式中,這時fx函式中的f指向test(),這裡就是上面閉包**講的函式的引用,然後執行兩句輸出語句,閉包上面講過,fx()函式裡面還沒有變數來呼叫fy()函式,所以編譯器只是會將它讀取一遍而不會執行它,這裡函式會先輸出:》-----------開始222222------------

》-----------結束222222-------------

然後程式執行到return fy時,這裡的fy是fx裡面定義的那個fy函式,這些**就是fx(test())執行後返回了fy()這個函式。這裡返回函式時後面不能加括號,因為這是乙個函式的引用,這裡返回的fy會賦值給另乙個函式。
2.所以funx(fx(test()))就變成了funx(fy),這時,將fy函式傳入funx函式中,funx裡面的f函式就指向了fy,這裡和上面的情況一樣,不會執行funy函式,只是會將return前面不屬於funy函式裡面的**執行一遍,所以這裡會輸出:
》-----------開始111111------------

》-----------結束111111-------------

程式讀取到return funy 時,跳出函式,然後我們這句funx(fy)就變成funy了,這句就變成了執行funy函式,然後我們來看funy函式:
deffuny():

f()print('函式內111111。。。。')

3.這裡是第三步了,我們執行funy函式,首先執行f(),這裡的f()就是一開始指向的fy函式,所以f()就是執行fy()函式,有可能有人這裡有些不懂,這裡為什麼f()為什麼指向的是fy()函式呢,我們可以反向推導,f()是由哪個函式引用過來的呢,這裡我就不仔細多講,我們執行fy()函式,這段**是:
deffy():

f()print('函式內222222。。。。')

這裡進入fy()函式,執行f()函式,因為這裡的f函式是由test傳過來的,所以這裡的f()函式時test()函式,所以會輸出:
print('test......')
然後執行後面那句print(『函式內222222。。。。』),所以會輸出:
》函式內222222。。。。
4.程式到這裡就把funx中的f()這句執行完畢,然後執行下一句
print('函式內111111。。。。')
輸出:
》函式內111111。。。。
其結果就是如此,這就是裝飾器的執行步驟,一遍看不懂可以多看幾遍,難點及時函式之間的引用和呼叫,搞清楚這一點就說明理解裝飾器了。

python 閉包 裝飾器

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

閉包 裝飾器

外部函式返回內部函式的引用 內部函式可以直接使用外部函式的環境變數 語法 外部函式通過返回內部函式的引用 內部函式可以直接使用外部函式的 環境變數 自由變數 函式執行時間統計 執行函式前預備處理 執行函式後清理功能 許可權校驗等場景 快取有且只有乙個引數 指向了被裝飾的函式的引用 使用裝飾器 裝飾器...

閉包,裝飾器

多層函式巢狀,函式裡面還有定義函式,一般是兩個 往往內層函式會用到外層函式的變數,把內層函式以及外部函式的變數當成乙個特殊的物件,這就是閉包。閉包比物件導向更純淨 更輕量,既有資料又有執行資料的 比普通函式功能更強大,不僅有 還有資料 利用閉包的基本原理,對乙個目標函式進行裝飾,即在執行乙個目標函式...