中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python閉包和裝飾器怎么用

發布時間:2022-01-26 15:05:10 來源:億速云 閱讀:141 作者:zzz 欄目:開發技術

這篇“python閉包和裝飾器怎么用”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“python閉包和裝飾器怎么用”文章吧。

一、閉包

閉包的形成條件:

1.函數嵌套。

2.內部函數使用了外部函數的變量或者參數。

3.外部函數返回了使用外 部變量的內部函數。

二、一個簡單的例子

def func_out(num1):
    def inner(num2):
        res = num1 + num2
        print(res)
    return inner
# a = func_out(10)(10)
a = func_out(10)
a(10)

閉包修改外部函數的變量:

在閉包內修改外部函數的變量需要使用nonlocal關鍵字

def func_out():
    # 外部函數的變量
    num1 = 10
    def func_inner():
        # 在閉包內修改外部函數的變量
        nonlocal num1
        num1 = 20
        res = num1 +20
        print(res)
    print("修改前的變量", num1)
    func_inner()
    print("修改后的變量", num1)
    return func_inner
new_func = func_out()
new_func()

三、裝飾器

3.1 簡單裝飾器

裝飾器就是給已有函數增加額外功能的函數,它本質上就是一個閉包函數,也就是說也是一個函數嵌套。裝飾器的功能特點:

1.不修改已有函數的源代碼

2.不修改已有函數的調用方式

3.給已有函數增加額外的功能

用戶在發表評論的時候需要驗證用戶是否登錄,我們首先會想到去修改原來的函數,在函數里面添加一些功能,但是在現在這分工合作的時代,這樣的修改很容易出現修改了祖傳的代碼后,函數出現問題,也影響代碼的高效復用。為了能夠不重新修改原來的評論的代碼,實現高水平的代碼復用。

原本的函數及其調用:

def comment():
    print("執行祖傳代碼.....")
    print("發表評論")
# 調用評論功能
comment()

自己手寫一個實現裝飾器功能的函數實現登錄驗證:

def decorator(func):
    def inner():
        print('正在驗證登錄者身份...
驗證成功')
        func()
    return inner


def comment():
    print("執行祖傳代碼.....")
    print("發表評論")
# 調用評論功能
comment = decorator(comment)
comment()

輸入結果:

正在驗證登錄者身份…
驗證成功
執行祖傳代碼…
發表評論

3.1.1 使用裝飾器的語法糖

裝飾器的語法糖寫法:@裝飾器名稱

如例子可以改寫為:

def decorator(func):
    def inner():
        print('正在驗證登錄者身份...
驗證成功')
        func()
    return inner

@decorator
def comment():
    print("執行祖傳代碼.....")
    print("發表評論")

# 調用函數
comment()

運行結果:

正在驗證登錄者身份…
驗證成功
執行祖傳代碼…
發表評論

3.1.2 裝飾器的執行時機

先說結論:在使用裝飾器語法糖時,會先將該裝飾器函數執行一遍。

def decorator(func):
    # 測試裝飾器的執行時機
    print('--remark1----')
    def inner():
        print('正在驗證登錄者身份...
驗證成功')
        func()
    print('----remark2---')
    return inner

@decorator
def comment():
    print("執行祖傳代碼.....")
    print("發表評論")

輸出結果:

–remark1----
----remark2—

3.2 通用裝飾器

裝飾的函數可能有參數傳遞,或者有返回值,上面寫的例子中,如果依然用上面的方法及逆行裝飾器的裝飾將會出現問題,那是否有一個通用的裝飾器能夠裝飾任意函數呢?

3.2.1 裝飾帶有參數的函數
def logging(fn):
    def inner(num1,num2):
        print('執行了一次計算')
        fn(num1,num2)
    return inner
# 使用裝飾器裝飾函數
@logging
def sum_num(a,b):
    result = a + b
    print(result)
    
sum_num(1,2)
3.2.2. 裝飾帶有返回值的函數:
def logging(fn):
    def inner(num1,num2):
        print('執行了一次計算')
        result = fn(num1,num2)
        return result
    
    return inner
# 使用裝飾器裝飾函數
@logging
def sum_num(a,b):
    result = a + b
    return result
    
print(sum_num(1,2))
3.2.3 實現通用裝飾器

*args: 用于接收元組參數,可傳可不傳

**kwargs: 用于接收字典類型參數,可傳可不傳

def logging(fn):
    def inner(*args, **kwargs):
        result = fn(*args, **kwargs)
        return result
    return inner

@logging
def sum_num(a,b):
    result = a + b
    return result

3.3 多個裝飾器的使用

多個裝飾器的過程:由內到外的裝飾過程,先執行內部裝飾器,再執行外部裝飾器。

原理剖析:content = make_div(make_p(content))

分步拆解:content = make_p(content), 內部裝飾器完成content=make_p.inner, content = make_div(make_p.inner)

def make_div(func):
    print("make_div裝飾器執行了")
    def inner():
        # 在內部函數對已有函數進行裝飾
        result = "<div>" + func() +"</div>"
        return result
    return inner

def make_p(func):
    print("make_p裝飾器執行了")
    def inner():
        # 在內部函數對已有函數進行裝飾
        result = "<p>" + func() +"</p>"
        return result
    return inner

@make_div
@make_p
def content():
    return "人生苦短,我用Python"

輸出:

make_p裝飾器執行了
make_div裝飾器執行了
<div><p>人生苦短,我用Python</p></div>

3.4 帶有參數的裝飾器

帶有參數的裝飾器時機上就是定義了一個函數,讓函數接收參數,再函數內部返回該裝飾器。

如定義一個能夠判斷加減的裝飾器:

def return_decorator(flag):
    def decorator(func):
        def inner(a,b):
            if flag == '+':
                print("正在進行加法運算")
            elif flag == '-':
                print("正在進行減法運算")
            func(a,b)
        return inner
    return decorator
@return_decorator('+')
def add_num(a,b):
    print(a+b)

add_num(1,5)

3.5 類裝飾器

使用類裝飾已有函數。

class MyDecorator(object):
    def __init__(self,func):
        self.__func = func
    # 實現__call__方法,讓對象變成可調用的對象,
    # 可調用的對象能夠像函數一樣被使用。
    def __call__(self,*args,**kwargs):
        # 對已有參數進行封裝
        print('--正在進行裝飾-----')
        self.__func()
        
@MyDecorator
def show():
    print("hello")

# 指向MyDecorator類創建實例對象--> show()==> 對象()
show()

輸出:

–正在進行裝飾-----
hello

以上就是關于“python閉包和裝飾器怎么用”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

台南县| 临高县| 青神县| 安西县| 隆林| 南岸区| 赫章县| 重庆市| 惠东县| 额尔古纳市| 都江堰市| 建昌县| 纳雍县| 高阳县| 安阳市| 剑川县| 达孜县| 囊谦县| 板桥市| 鹿邑县| 五指山市| 区。| 奉节县| 西乡县| 正安县| 桐梓县| 会东县| 新兴县| 随州市| 玉山县| 富裕县| 青浦区| 南开区| 吴川市| 墨江| 弥渡县| 伊春市| 富川| 盖州市| 邯郸市| 福安市|