1. 程式人生 > 資訊 >東南亞地區新冠病毒疫情惡化,越南多家晶片工廠停工

東南亞地區新冠病毒疫情惡化,越南多家晶片工廠停工

python閉包

閉包並不只是一個python中的概念,它在函數語言程式設計語言中應用較為廣泛。

在這裡,我們只淺談python閉包。

閉包,又稱閉包函式或者閉合函式,閉包中外部函式返回的不是一個具體的值,而是一個函式。一般情況下,返回的函式會賦值給一個變數,這個變數可以在後面被繼續執行呼叫。

我們來看一個例子

def a(param1):
    def b(param2):
        return param1 + param2
    return b

fun1 = a(1)#基數1
fun2 = a(2)#基數2
fun3 = a(3)#基數3

print(fun1(1)) #1+1
print(fun2(1)) #2+1
print(fun3(1)) #3+1

函式a的返回是函式b,而函式b的返回是a之前的param1加上b裡再給的引數param2。

我們可以這樣形象地認為,fun1是相加的函式,而第一個加數已經在定義fun1的時候鎖死了,我們傳給它的引數只能是第二個加數。

接下來,我們定義a(param1)是外函式,b(param2)是內函式,這樣來解釋閉包:

在一個外函式中定義了一個內函式,內函式裡運用了外函式的臨時變數,並且外函式的返回值是內函式的引用。

我們在例子中加入一些print

def a(param1):
    print(a)
    def b(param2):
        print(b)
        return param1 + param2
    return b

fun1 = a(1)
fun2 = a(2)
fun3 = a(3)

print(fun1(1),fun1(1),fun2(2),fun3(3))

執行,得到

<function a at 0x000001AC399668B0>
<function a at 0x000001AC399668B0>
<function a at 0x000001AC399668B0>
<function a.<locals>.b at 0x000001AC39966940>
<function a.<locals>.b at 0x000001AC39966940>
<function a.<locals>.b at 0x000001AC399669D0>
<function a.<locals>.b at 0x000001AC39966A60>
2 2 4 6

這可以看出,在記憶體中,外部函式a是隻存在唯一一個的,而它的內部函式b是一樣的程式碼,不一樣的物件。

淺顯地說到這裡,深入的話我推薦一篇部落格

理解Python閉包概念

python裝飾器

在瞭解了閉包這個概念之後,我相信裝飾器就可以很好理解了。

這裡,也從一個簡單的例子說起。

def makebold(fn):  
    def wrapped():  
        return "<b>" + fn() + "</b>"  
    return wrapped  
   
def makeitalic(fn):  
    def wrapped():  
        return "<i>" + fn() + "</i>"  
    return wrapped  

def welcome():
    return "hello world" 

a=makeitalic(welcome)
b=makebold(a)
print(a())
print(b())

#結果
#<i>hello world</i>
#<b><i>hello world</i></b>

我們在兩個函式裡內嵌的不同的wrapped函式,負責給我們的"hello world" 左右新增起始閉合標籤。這就是python 中裝飾器做的事情,封裝一個函式,並用自己的方法來修改它的行為。

當然,這裡沒有出現@符號,這是一種語法糖,我們給它加上。

什麼是語法糖?

在不改變其所在位置的語法結構的前提下,實現了執行時等價。

eg:在 C 語言裡用 a[i] 表示 *(a+i),用 a[i][j] 表示 *(*(a+i)+j)

def makebold(fn):  
    def wrapped():  
        return "<b>" + fn() + "</b>"  
    return wrapped  
   
def makeitalic(fn):  
    def wrapped():  
        return "<i>" + fn() + "</i>"  
    return wrapped  

@makebold
@makeitalic
def welcome():
    return "hello world" 

print(welcome())

#輸出<b><i>hello world</i></b>

參考

理解Python閉包概念

flask之路由route