欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python函數(shù)裝飾器的使用詳解

 更新時(shí)間:2022年01月14日 15:57:47   作者:DgLink  
大家好,本篇文章主要講的是Python函數(shù)裝飾器的使用詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下

裝飾器

裝飾器的定義

關(guān)于裝飾器的定義,我們先來(lái)看一段github上大佬的定義:

Function decorators are simply wrappers to existing functions.
In the context of design patterns,decorators dynamically alter the functionality of a function, method or class without having to directly use subclasses.
This is ideal when you need to extend the functionality of functions that you don’t want to modify.
We can implement the decorator pattern anywhere, but Python facilitates the implementation by providing much more expressive features and syntax for that.

這段話的最主要的意思就是:

函數(shù)裝飾器是給已有函數(shù)的簡(jiǎn)單容器。
在原有的代碼環(huán)境下,它能夠動(dòng)態(tài)地改變一個(gè)函數(shù)的功能,或者不直接使用子類而改變方法和類。
當(dāng)你不想修改源代碼但又想實(shí)現(xiàn)功能上的擴(kuò)充的時(shí)候,這是一個(gè)不錯(cuò)的方法。
我們可以在任何情況下使用裝飾器樣式,同時(shí)Python通過(guò)提供更多強(qiáng)力的屬性和語(yǔ)法來(lái)幫助裝飾器的使用。

裝飾器的意義

在上文之中其實(shí)我們已經(jīng)知道了裝飾器的意義,
可以不需要修改源代碼就能夠直接做到功能的擴(kuò)充,但是為此我們需要付出的是更多的編寫(xiě)時(shí)間,
而且更為重要的是,通過(guò)修改源碼實(shí)現(xiàn)功能的增加往往會(huì)改變接口傳遞的參數(shù),可一個(gè)項(xiàng)目之中往往存在許多接口這也代表著你可能需要多次更改接口參數(shù),
這個(gè)工作量,我們可不干!

裝飾器的使用

無(wú)參裝飾器

無(wú)參裝飾器是最為基礎(chǔ)的裝飾器,
其根本原因在于裝飾的函數(shù)對(duì)象不需要仍和的參數(shù);
接下來(lái)示范一下最簡(jiǎn)單的裝飾器是如何實(shí)現(xiàn)的:

def greeting():						# 定義一個(gè)最基本的無(wú)參函數(shù)
    return "Hello,讀者老爺們!"
# 現(xiàn)在我需要實(shí)現(xiàn)的要求是:讓輸出的內(nèi)容變?yōu)?lt;p>"Hello,讀者老爺們"<p>
# 在不直接更改greeting函數(shù)的前提下,我們需要使用無(wú)參裝飾器
def decorator_p(func):				# 用于接收一個(gè)函數(shù)
	def wrapper():
		return f'<p>{func()}<p>'
	return wrapper
decorator = decorator_p(greeting)		# 調(diào)用decorator_p,并且用一個(gè)decorator接收返回值
print(decorator())

<p>Hello,讀者老爺們!<p>
以上就是輸出的結(jié)果

但是這個(gè)結(jié)果我其實(shí)并不滿意,
因?yàn)橥瓿闪斯δ芨郊又笪覀兙尤贿€需要再使用decorator = decorator_p(greeting)來(lái)接收一下,而且這樣的話調(diào)用方式就不再是原本的greeting()了,而是decorator()
這兩者對(duì)于追求高效優(yōu)雅的Python來(lái)說(shuō)已經(jīng)提供解決方法了,
讓我娓娓道來(lái):

# 針對(duì)于調(diào)用方式而言,我們首先想到的解決方法是
greeting = decorator_p(greeting)		# 將原本的greeting函數(shù)傳給decorator_p,而重命名
print(greeting())						# 輸出結(jié)果與原來(lái)相同
但這個(gè)仍然可以改進(jìn),這就要使用到Python提供的@,
但使用這種方法必須注意書(shū)寫(xiě)的順序,因此代碼必須這樣更改:
def decorator_p(func):
    def wrapper():
        return f'<p>{func()}<p>'
    return wrapper

@decorator_p					# 效果等同于 greeting = decorator_p(greeting)
def greeting():
    return "Hello,讀者老爺們!"
print(greeting())

<p>Hello,讀者老爺們!<p>

得到的結(jié)果是我們想要的,但使用這種方法順序格外重要,
如果這樣書(shū)寫(xiě),則會(huì)給出報(bào)錯(cuò):

@decorator_p						#使用這個(gè)@后,將會(huì)開(kāi)始向上尋找decorator_p這個(gè)函數(shù)
def greeting():
    return "Hello,讀者老爺們!"
print(greeting())

def decorator_p(func):
    def wrapper():
        return f'<p>{func()}<p>'
    return wrapper

NameError: name ‘decorator_p’ is not defined

給出的報(bào)錯(cuò)原因是因?yàn)闆](méi)有找到decorator_p這個(gè)函數(shù),
可明明我們已經(jīng)完成這個(gè)函數(shù)的定義了,
所以我們可以得到的結(jié)論便是:

當(dāng)使用@時(shí),就會(huì)開(kāi)始向上尋找函數(shù),當(dāng)找不到函數(shù)的時(shí)候就會(huì)報(bào)錯(cuò)

有參裝飾器

接下來(lái)介紹一下有參裝飾器,就是指需要傳遞參數(shù)的裝飾器,
上文之中其實(shí)已經(jīng)介紹過(guò)了關(guān)于無(wú)參裝飾器的使用,而有參裝飾器也并沒(méi)有多難,
來(lái)一個(gè)示范:

def decorator(func):
    def wrapper(name):
        return f'<p>{func(name)}<p>' 
    return wrapper

@decorator
def greeting(name):
    return f"Hello,{name}!"
print(greeting('讀者老爺'))		# 傳遞一個(gè)參數(shù)

<p>Hello,讀者老爺!<p>

實(shí)例練習(xí)

OK,經(jīng)過(guò)上文介紹所有讀者應(yīng)該又會(huì)處于似懂非懂的狀態(tài),
那么秉持一文一練的理念,我們接下來(lái)將通過(guò)編寫(xiě)登錄功能,仔細(xì)看一下使用裝飾器和不適用裝飾器的區(qū)別。
在開(kāi)始之前,我創(chuàng)建了一個(gè)文本文件夾,將會(huì)用于模擬用戶儲(chǔ)存的信息,內(nèi)容如下:

sign_in.txt
Joseph:Jostar
Jonasen:Jostar
Kujo:Jotaro
Jolin:Kujo
Diavollo:Doppio

需求清單:
1)用戶賬戶只能夠由數(shù)字和英文組成,長(zhǎng)度不超過(guò)16字符;
2)用戶密碼只能夠由數(shù)字和英文組成,長(zhǎng)度不超過(guò)16字符;
3)用戶擁有4次輸入的機(jī)會(huì)。

# 不使用任何函數(shù)
# 無(wú)裝飾器 登錄功能
count = 1				# 用于計(jì)算使用次數(shù)
while count < 5:
    user_account = input('請(qǐng)輸入你的賬號(hào)')
    if user_account.isalnum() and len(user_account) <= 16:		# 判斷賬號(hào)長(zhǎng)度和組成
        user_keyword = input('請(qǐng)輸入你的密碼')
        if user_keyword.isalnum() and len(user_keyword) <= 16:	# 判斷密碼的長(zhǎng)度和組成
            with open('sign_in.txt','r') as file:				# 打開(kāi)登錄文件核對(duì)登錄信息
                for line in file:
                    r_name, r_keyword = line.strip().split(':')
                    if r_name == user_account and r_keyword == user_keyword:
                        print('登錄成功')
                        break
                else:
                    count += 1
                    print(f'賬號(hào)密碼不匹配,還剩下{5-count}次機(jī)會(huì)')
                    continue
                break
        else:
            count += 1
            print(f'密碼輸入錯(cuò)誤,還剩下{5-count}次機(jī)會(huì)')
            continue
    else:
        count += 1
        print(f'輸入賬號(hào)錯(cuò)誤,還剩下{5-count}次機(jī)會(huì)')
        continue
else:
    print('機(jī)會(huì)已用完')

程序員之間總是流傳著這么一個(gè)梗,
開(kāi)發(fā)總是會(huì)看著一串代碼愣愣出神說(shuō)道:“這究竟是誰(shuí)寫(xiě)的代碼,像坨屎。”
然后過(guò)了良久突然說(shuō)“好像是我自己寫(xiě)的。”

接下來(lái)我們需要做的就是改良,使用裝飾器將其改良,
我們的源代碼將其固定成這樣:

# 只是單純的用戶輸入,
# 而后我們要在此基礎(chǔ)上不斷優(yōu)化,為其添加上判斷長(zhǎng)度、限制次數(shù)的功能
def input_signup():
    user_name = input('請(qǐng)輸入賬戶名字')
    user_keyword = input('請(qǐng)輸入賬戶密碼')
    return user_name, user_keyword
def passing_func(func1, func2, func3):
    def wrapper(func4):
        def decorator():
            count = 1
            while count < 5:
                name, keyword = func4()
                check = func1(name, keyword)
                if check is not True:
                    count += 1
                    print(f'你還剩下{5-count}次登錄機(jī)會(huì)')
                    continue
                check = func2(name, keyword)
                if check is not True:
                    count += 1
                    print(f'你還剩下{5-count}次登錄機(jī)會(huì)')
                    continue
                check = func3(name, keyword)
                if check is not True:
                    count += 1
                    print(f'你還剩下{5 - count}次登錄機(jī)會(huì)')
                    continue
                else:
                    break
        return decorator
    return wrapper


def limit_len(name, keyword, length=16):
    '''
    用于判斷用戶名字和密碼的長(zhǎng)度是否符合標(biāo)準(zhǔn)
    :param   name:用于接受用戶的名字
    :param   keyword:用于接受用戶的密碼
    :param   length:默認(rèn)參數(shù)為16
    :return: check:用于判斷輸入是否符合長(zhǎng)度標(biāo)準(zhǔn),詳細(xì)請(qǐng)見(jiàn)裝飾器中的使用
    '''

    check = True
    if len(name) > length or len(keyword) > length:
        print('賬號(hào)名或密碼長(zhǎng)度不符合規(guī)范')
        check = False
        return check
    return check


def limit_composition(name, keyword):
    '''
    用于判斷用戶名字和密碼的組成是否符合標(biāo)準(zhǔn)
    :param   name:用于接受用戶的名字
    :param   keyword:用于接受用戶的密碼
    :return: check:用于判斷輸入是否符合長(zhǎng)度標(biāo)準(zhǔn),詳細(xì)請(qǐng)見(jiàn)裝飾器中的使用
    '''

    check = True
    if name.isalnum() is not True or keyword.isalnum() is not True:
        print('賬號(hào)名或密碼組成不符合規(guī)范')
        check = False
        return check
    return check


def verify_useinfo(name, keyword):
    '''
    用于檢驗(yàn)用戶輸入的賬號(hào)和密碼是否符合文件中儲(chǔ)存的
    :param   name:用于接受用戶的名字
    :param   keyword:用于接受用戶的密碼
    :return: check:用于判斷輸入是否符合長(zhǎng)度標(biāo)準(zhǔn),詳細(xì)請(qǐng)見(jiàn)裝飾器中的使用
    '''
    check = True
    with open('sign_in.txt','r') as file:
        for line in file:
            r_name, r_keyword = line.strip().split(':')
            if r_name == name and r_keyword == keyword:
                print('登錄成功,歡迎使用')
                return check
        else:
            check = False
            print('賬號(hào)密碼錯(cuò)誤,請(qǐng)重新輸入')
            return check


@passing_func(limit_len, limit_composition, verify_useinfo)
def input_signup():
    user_name = input('請(qǐng)輸入賬戶名字')
    user_keyword = input('請(qǐng)輸入賬戶密碼')
    return user_name, user_keyword

以上就是關(guān)于裝飾器的所有內(nèi)容了,
希望能夠?qū)λ凶x者有所幫助。

總結(jié)

到此這篇關(guān)于Python函數(shù)裝飾器的使用詳解的文章就介紹到這了,更多相關(guān)Python函數(shù)裝飾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解python中mongoengine庫(kù)用法

    詳解python中mongoengine庫(kù)用法

    這篇文章主要介紹了python中mongoengine庫(kù)用法,主要包括MongoDB的安裝與連接過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • win10下python2和python3共存問(wèn)題解決方法

    win10下python2和python3共存問(wèn)題解決方法

    在本篇文章里小編給大家整理了關(guān)于win10下python2和python3共存問(wèn)題解決方法,有興趣的朋友們參考下。
    2019-12-12
  • Python3中延時(shí)變量和 free_list鏈表的區(qū)別解析

    Python3中延時(shí)變量和 free_list鏈表的區(qū)別解析

    這篇文章主要介紹了Python3中延時(shí)變量和 free_list鏈表的區(qū)別,在Python3中,"延時(shí)變量" 和 "free_list鏈表" 是兩個(gè)不同的概念,他們之間沒(méi)有直接聯(lián)系,本文給實(shí)例相結(jié)合給大家講解的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • Matplotlib繪圖基礎(chǔ)之子圖詳解

    Matplotlib繪圖基礎(chǔ)之子圖詳解

    這篇文章主要為大家詳細(xì)介紹了Matplotlib繪制子圖的常用方式和技巧,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下
    2023-07-07
  • python中l(wèi)ist列表的高級(jí)函數(shù)

    python中l(wèi)ist列表的高級(jí)函數(shù)

    這篇文章主要為大家詳細(xì)介紹了python中l(wèi)ist列表的高級(jí)函數(shù),感興趣的小伙伴們可以參考一下
    2016-05-05
  • Python實(shí)現(xiàn)批量自動(dòng)整理文件

    Python實(shí)現(xiàn)批量自動(dòng)整理文件

    本文將利用Python制作一個(gè)批量自動(dòng)整理文件的小工具,可以自定義整理某一個(gè)路徑下面的所有需要被整理的文件。感興趣的小伙伴可以了解一下
    2022-03-03
  • python中實(shí)現(xiàn)php的var_dump函數(shù)功能

    python中實(shí)現(xiàn)php的var_dump函數(shù)功能

    這篇文章主要介紹了python中實(shí)現(xiàn)php的var_dump函數(shù)功能,var_dump函數(shù)在PHP中調(diào)試時(shí)非常實(shí)用,本文介紹在Python中實(shí)現(xiàn)這個(gè)函數(shù),需要的朋友可以參考下
    2015-01-01
  • Python SQLite3簡(jiǎn)介

    Python SQLite3簡(jiǎn)介

    這篇文章主要為大家詳細(xì)介紹了Python SQLite3的簡(jiǎn)單介紹以及使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Django--權(quán)限Permissions的例子

    Django--權(quán)限Permissions的例子

    今天小編就為大家分享一篇Django--權(quán)限Permissions的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-08-08
  • Python基于pandas實(shí)現(xiàn)json格式轉(zhuǎn)換成dataframe的方法

    Python基于pandas實(shí)現(xiàn)json格式轉(zhuǎn)換成dataframe的方法

    這篇文章主要介紹了Python基于pandas實(shí)現(xiàn)json格式轉(zhuǎn)換成dataframe的方法,結(jié)合實(shí)例形式分析了Python使用pandas模塊操作json數(shù)據(jù)轉(zhuǎn)換成dataframe的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2018-06-06

最新評(píng)論