首頁 > 軟體

python中的閉包和裝飾器的使用範例

2022-11-21 14:01:34

函數引數

在python中,函數可以當作引數使用

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


# func01()
# 函數名存放的是函數所在空間的地址
# print(func01)
# 函數名也可以像普通變數一樣賦值
# func02 = func01
# func02()

def foo(func):
    func()


foo(func01)

閉包的構成條件

1.在函數巢狀(函數裡面再定義函數)的前提下
2.內部函數使用了外部函數的變數(還包括外部函數的引數)
3.外部函數返回了內部函數

# 閉包的構成條件:
# 1在函數巢狀(函數裡面再定義函數)的前提下

def func_out(num1):
    def func_inner(num2):
        # 2內部函數使用了外部函數的變數(還包括外部函數的引數)
        num = num1 + num2
        print("num的值為", num2)

    # 3外部函數返回了內部函數
    return func_inner


# 建立閉包範例
f = func_out(10)
# 執行閉包
f(1)
f(2)

基礎的閉包的使用

# 外部函數
def config_name(name):
    # 內部函數
    def say_info(info):
        print(name + ":" + info)

    return say_info
tom = config_name("tom")
tom("你好")
tom("你在嗎")

jerry = config_name("jerry")
jerry("你好")
jerry("我在呢")

# 外部函數
def config_name(name):
    # 內部函數
    def say_info(info):
        print(name + ":" + info)

    return say_info


tom = config_name("tom")
tom("你好")
tom("你在嗎")

jerry = config_name("jerry")
jerry("你好")
jerry("我在呢")

nonloal關鍵字的使用

1.非區域性宣告變數指代的已有識別符號是最近外面函數的已宣告變數,但是不包括全域性變數。這個是很重要的,因為繫結的預設行為是首先搜尋本地名稱空間。nonlocal宣告的變數只對區域性起作用,離開封裝函數,那麼該變數就無效。
2.非區域性宣告不像全域性宣告,我們必須在封裝函數前面事先宣告該變數
3.非區域性宣告不能與區域性範圍的宣告衝突

# 外部函數
def func_out(num1):
    # 內部函數
    # aaa = 10

    def func_inner(num2):
        nonlocal num1
        num1 = num2 + 10
    print(num1)
    func_inner(10)
    print(num1)

    return func_inner
# num1 = 10
# f = func_out(10)
# 呼叫閉包 = 內部函數 num2 = 10
# f(10)

func_out(10)

基礎程式碼實現(裝飾器)

# 1.定義一個裝飾器(裝飾器的本質是閉包)
def check(fn):
    def inner():
        print("登入驗證")
        fn()

    return inner

# 需要被裝飾的函數
def comment():
    print("發表評論")

# 2使用裝飾器裝飾函數(增加一個登入功能)
comment = check(comment)
comment()

裝飾器的基本使用

# 1定義一個裝飾器(裝飾器的本質是閉包)
def check(fn):
    def inner():
        print("請先登陸")
        fn()

    return inner
# 2使用裝飾器裝飾函數(增加一個登陸功能)
# 直譯器遇到@check 會立即執行 comment = check(comment)

@check
def comment():
    print("發表評論")
comment()

裝飾器的使用

import time
# 1 定義裝飾器
def get_time(fn):
    def inner():
        start = time.time()
        fn()
        end = time.time()

        print("時間:", end - start)

    return inner

# 2 裝飾函數
# 要被裝飾的函數
@get_time
def func():
    for i in range(100000):
        print(i)
func()

有引數的裝飾器的使用

# 定義裝飾器
def logging(fn):  # fn = sum_num
    def inner(a, b):
        fn(a, b)

    return inner  # sum_num = inner

# 使用裝飾器裝飾函數
@logging
def sum_num(a, b):
    result = a + b
    print(result)
sum_num(1, 2)

帶有返回值的裝飾器

# 定義裝飾器
def logging(fn):  # fn = sum_num
    def inner(a, b):
        result = fn(a, b)
        return result

    return inner  # sum_num = inner

# 使用裝飾器裝飾函數
@logging
def sum_num(a, b):
    result = a + b
    return result
result = sum_num(1, 2)
print(result)

帶有不定長引數的裝飾器

# 定義裝飾器
def logging(fn):  # fn = sum_num
    def inner(*args, **kwargs):
        fn(*args, **kwargs)

    return inner  # sum_num = inner

# 使用裝飾器裝飾函數
@logging
def sum_num(*args, **kwargs):
    print(args, kwargs)
sum_num(1, 2, 3, age="18")

帶有引數的裝飾器的使用

# 裝飾器
def logging(flag):  # flag = "+"

    # 外部函數
    def decorator(fn):
        # 內部函數
        def inner(num1, num2):
            # 判斷流程
            if flag == "+":
                print("--正在努力加法計算--")
            elif flag == "-":
                print("--正在努力減法計算--")
            result = fn(num1, num2)
            return result

        return inner

    # 返回裝飾器
    return decorator
# 被帶有引數的裝飾器裝飾的函數
@logging('+')  # 1 logging("+") 2 @decorator起到裝飾器的功能了
def add(a, b):
    result = a + b
    return result
# 執行函數
result = add(1, 3)
print(result)

類裝飾器的使用

# 定義類裝飾器
class Check(object):
    def __init__(self, fn):
        self.__fn = fn

    def __call__(self, *args, **kwargs):
        print("登入")
        self.__fn()
@Check
def comment():
    print("發表評論")
comment()

到此這篇關於python中的閉包和裝飾器的使用的文章就介紹到這了,更多相關python閉包和裝飾器內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com