1. 程式人生 > >Python高階——閉包與裝飾器

Python高階——閉包與裝飾器

閉包

1.函式引數: (1)函式名存放的是函式的地址 (2)函式名()存放的是函式內的程式碼 (3)函式名只是函式程式碼空間的引用,當函式名賦值給一個物件的時候,就是引用傳遞

def func01():
    print("func01 is show")

test = func01
print(func01)
print(test)
test()

結果: 這裡寫圖片描述

2.閉包: (1)內層函式可以訪問外層函式變數

(2)閉包就是一個巢狀定義的函式,在外層執行時才開始內層函式的定義,然後將內部函式的引用傳遞函式外的物件(閉包外層函式的返回值為內層函式名)

(3)內部函式和使用的外部函式提供的變數構成的整體稱為閉包

def func_out(rate):
    def func_in(money):
        print(rate * money)
    return func_in


usa_money = func_out(0.7)
usa_money(100)
usa_money(200)

執行結果: 這裡寫圖片描述

裝飾器

裝飾器就是在不改變函式的原有程式碼的前提下 給函式新增新的功能,裝飾器一般是一個閉包。 1.裝飾器:

# 在不改變函式的原有程式碼的前提下 給函式新增新的功能
def func_out(func):
    def func_in():
        print("驗證"
) func() return func_in @func_out def login(): print("登入") # 有裝飾器 裝飾器下面正好是一個函式 # login = func_out(login) 重點 login()

如果@func_out裝飾器下剛好是一個login函式,會執行:

login = func_out(login)

所以會直接執行func_out內的程式碼,func為原login,即指向原login函式的地址空間並且返回內層函式名,即:

login = func_out(login) = func_in

所以login()的執行結果為func_in(),即:

print('驗證')
func()  # func指原login函式的地址

就實現了不改變原函式的情況下給函式新增新功能 執行結果: 這裡寫圖片描述

2.裝飾有返回指函式:

def func_out(func):
    def func_in():
        # ret = func()
        #   def login():
        #       return 100
        return func()
    return func_in


@func_out
def login():
    return 100
# login() ==> func_in()
# func ==> 原始的login


f = login()
print(f)

3.裝飾有引數函式:

def func_out(func):
    def func_in(a):
        func(a)

    return func_in


@func_out
def login(a):
    print(a)
# login() ==> func_in()
# func ==> 原始的login


login(10)

4.裝飾器通用版:

def func_out(func):
    def func_in(*args,**kwargs):
        return func(*args,**kwargs)

    return func_in

@func_out
def login(*args,**kwargs):
    print(args)
    print(kwargs)

# login() ==> func_in()
# func ==> 原始的login

login(10,20,age = "17",name="123")

5.類裝飾器:

class Foo(object):
    def __init__(self, func):
        self.func = func

    def __call__(self):
        print("驗證")
        self.func()


@Foo
def login():
    print("登入")

# login = Foo(login)

login()

6.多裝飾器:

def func_out01(func01):
    print("func_out01 is show")

    def func_in01():
        print("func_in01 is show")
        func01()

    return func_in01


def func_out02(func02):
    print("func_out02 is show")

    def func_in02():
        print("func_in02 is show")
        func02()

    return func_in02


@func_out02  # login = func_out02(login)
@func_out01  # login = func_out01(login)
def login():
    print("login is show")


login()

執行結果: 因為@閉包名下為函式時才會實現裝飾器,所以func_out1會先裝飾函式,func_out2會後裝飾函式,所以外層函式先執行func_out1,後執行func_out2;因為func_out1先裝飾函式,func_out2後裝飾函式,所以func_out1裝飾後,原函式為先輸出func_in1內的語句,再輸出原login,然後func_out2裝飾後,執行順序為先輸出func_in2的語句,再輸出裝飾後的login函式,即:func_in2——func_in1——login。

這裡寫圖片描述

7.給裝飾器傳遞函式:

def route(引數):
    print(引數)
    def func_out(func):
        def func_in():
            func()
        return func_in
    return func_out


@route(引數)
def index():
    return "index is show"