Python的閉包(簡單閉包,裝飾器,多層裝飾器,裝飾器工廠)

瞭解閉包之前我們要先知道什麼是函數式編程,什麼是調用函數,什麼是引用函數。

# 函數式編程:把函數作爲函數的參數以及返回值的變成方式

# def work1():
#     print('這是被引用的函數')
# #調用函數
# work1()


# #引用函數
# w = work1  #地址指針指向這個地址
#
# print(id(work1))
# print(id(w))



def wrapper():      #外層
    print('start')

    def inner():        #內層
        print('inner')

    print('end')
    return inner     #外層返回內層函數名

# # 1:
wrapper()       #只運行了外層

# 2:
# inner = wrapper()     #運行了外層和內層
# inner()

對調用、引用函數有了一定了解後,就可以接觸閉包概念了

# 閉包是由函數及其相關的引用環境組合而成的實體
# (即:閉包=函數+引用環境)
# (想想Erlang的外層函數傳入一個參數a, 內層函數依舊傳入一個參數b, 內層函數使用a和b, 最後返回內層函數)

def line(a,b):

    def line_obj(x):
        nonlocal a       #   global適用於函數內部修改全局變量的值  nonlocal適用於嵌套函數中內部函數修改外部變量的值
        a += 1
        return a*x+b        #返回函數對值的操作

    return line_obj       #返回內部定義的函數名,但不運行

line1 = line(1,1)       #將line1的指針指向line的地址,這部操作實際上是引用line裏定義的函數line_obj的函數名
result = line1(2)       #實質上傳參並運行line_obj
print(result)

閉包的簡單應用:求一個平均數

'''用閉包求平均數'''

def A(a,b):

    def B():
        nonlocal a,b
        c = (a+b)/2
        return c
    return B

a=A(1,3)
print(a())

裝飾器是閉包的應用,下面是一個簡單的裝飾器

def one(func):
    print('1')
    def two():
        print('2')
        func()
    return two

#  @ 是裝飾器的語法糖
@one   #等價於 demo = one ( demo )
def demo():
    print('3')

demo()

下面是一個簡單的多層裝飾器

# 裝飾器避免冗餘代碼
def w1(func):
    def inner():
        print('w1 inner')
        func()
    return inner


def w2(func):
    def inner():
        print('w2 inner')
        func()
    return inner

#  @ 是裝飾器的語法糖
# 多個裝飾器的調用順序是自下往上,但是運行時的執行順序是自上往下!!!
@w2   # f2 = w2(f2)
@w1   # f1 = w1 (f1)
def f1():
    print('f1')


f1()

裝飾器工廠就是生產裝飾器的函數,下面是一個簡單的裝飾器工廠函數:

# 根據參數不同,生產不同的裝飾器


def factory(arg=None):    #工廠函數
    def timefun(func):   #裝飾器
        def inner():
            if arg:
                print('有')
            else:
                print('沒')
            return func()
        return inner
    return timefun

@factory(1)     #這裏的()一定要有
def f():
    print('f')

f()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章