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

python必學知識之裝飾器詳解

 更新時間:2023年09月22日 10:19:55   作者:生有涯,知無涯  
這篇文章主要介紹了python必學知識之裝飾器詳解,python的三大器指的是:裝飾器、迭代器、生成器,下面就裝飾器整理一下從各種資源收獲的對裝飾器的理解,需要的朋友可以參考下

1.函數(shù)引用的概念

理解裝飾器之前先要理解函數(shù)引用的概念

def func():
	print("hello world!")
# 調(diào)用函數(shù)
func()
# 引用函數(shù)
ret = func
print(id(ret))
print(id(func))
# 通過引用調(diào)用函數(shù)
ret()

運行結果ret和func的id相同,python里一切皆對象,函數(shù)名也是一個對象,ret是func函數(shù)的引用,它也指向func函數(shù)?;蛘呤呛瘮?shù)名僅僅是個變量,只不過指向了定義的函數(shù)而已,所以才能通過 函數(shù)名() 調(diào)用

2.理解閉包的概念

理解:先定義一個函數(shù),然后在該函數(shù)內(nèi)部再定義一個函數(shù),并且這個函數(shù)用到了外邊函數(shù)的變量,那么將這個函數(shù)以及用到的一些變量稱之為閉包

# 定義一個函數(shù)
def func(num1):
	 # 在函數(shù)內(nèi)部再定義一個函數(shù),并且這個函數(shù)用到了外邊函數(shù)的變量,那么將這個函數(shù)以及用到的一些變量稱之為閉包
	def wrapper(num2):
		# 在python3中,如果要修改外部函數(shù)的變量,需要加一條申明: nonlocal 外部變量名
		# nonlocal num1
		# num += 1
		print("%s * %s 的積是%s" % (num1, num2, num1 * num2))
		return num1 * num2
	# 其實這里返回的就是閉包的結果,即返回內(nèi)層函數(shù)的引用
	return wrapper
# 給func函數(shù)賦值,這個20就是給參數(shù)num1
ret = func(20)    # 等價于ret = wrapper
# 注意這里的100其實給參數(shù)num2
print(ret(100))    # 等同于 print(wrapper(100))

運行結果將會顯示 20 * 100 的積是2000 注意點: 由于閉包引用了外部函數(shù)的局部變量,則外部函數(shù)的局部變量沒有及時釋放,消耗內(nèi)存

3.裝飾器

裝飾器是程序開發(fā)中經(jīng)常會用到的一個功能,用好了裝飾器,開發(fā)效率如虎添翼,所以這也是Python面試中必問的問題。 假設下以下場景:

1.公司原本開發(fā)了一套軟件,各個部門一起合作開發(fā),目前公司有條不紊的進行著,但是,以前基礎平臺的開發(fā)人員在寫代碼時候沒有關注驗證相關的問題,即需要增加以下功能:在所有功能執(zhí)行前,先進行權限驗證。

2.老大把工作交給 Low B,他是這么做的: 跟每個業(yè)務部門交涉,每個業(yè)務部門自己寫代碼,調(diào)用基礎平臺的功能之前先驗證。這樣一來基礎平臺就不需要做任何修改了。

太棒了,有充足的時間泡妹子… 當天Low B 被開除了…

3.老大把工作交給 Low BB,他是這么做的:

############### 基礎平臺提供的功能如下 ############### 
def f1():
    # 驗證1
    # 驗證2
    # 驗證3
    print('f1')
def f2():
    # 驗證1
    # 驗證2
    # 驗證3
    print('f2')
def f3():
    # 驗證1
    # 驗證2
    # 驗證3
    print('f3')
def f4():
    # 驗證1
    # 驗證2
    # 驗證3
    print('f4')
############### 業(yè)務部門不變 ############### 
### 業(yè)務部門A 調(diào)用基礎平臺提供的功能### 
f1()
f2()
f3()
f4()
### 業(yè)務部門B 調(diào)用基礎平臺提供的功能 ### 
f1()
f2()
f3()
f4()
過了一周 Low BB 被開除了…

4.老大把工作交給 Low BBB,他是這么做的: 只對基礎平臺的代碼進行重構,其他業(yè)務部門無需做任何修改

############### 基礎平臺提供的功能如下 ############### 
def check_login():
    # 驗證1
    # 驗證2
    # 驗證3
    pass
def f1():
    check_login()
    print('f1')
def f2():
    check_login()
    print('f2')
def f3():
    check_login()
    print('f3')
def f4():
    check_login()
    print('f4')

老大看了下Low BBB 的實現(xiàn),嘴角漏出了一絲的欣慰的笑,語重心長的跟Low BBB聊了個天:

5.老大說: 寫代碼要遵循開放封閉原則,雖然在這個原則是用的面向?qū)ο箝_發(fā),但是也適用于函數(shù)式編程,簡單來說,它規(guī)定已經(jīng)實現(xiàn)的功能代碼不允許被修改,但可以被擴展,即:

  • 封閉:已實現(xiàn)的功能代碼塊
  • 開放:對擴展開發(fā)

如果將開放封閉原則應用在上述需求中,那么就不允許在函數(shù) f1 、f2、f3、f4的內(nèi)部進行修改代碼,老板就給了Low BBB一個實現(xiàn)方案:

def w1(func):
    def inner():
        # 驗證1
        # 驗證2
        # 驗證3
        func()
    return inner
@w1
def f1():
    print('f1')
@w1
def f2():
    print('f2')
@w1
def f3():
    print('f3')
@w1
def f4():
    print('f4')

對于上述代碼,也是僅僅對基礎平臺的代碼進行修改,就可以實現(xiàn)在其他人調(diào)用函數(shù) f1 f2 f3 f4 之前都進行【驗證】操作,并且其他業(yè)務部門無需做任何操作。

4.詳解裝飾器

4.1 裝飾器執(zhí)行流程

在這里插入圖片描述

4.2 帶多個參數(shù)的裝飾器

例如記錄某個函數(shù)的執(zhí)行時間

import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner
@timer   #==> func2 = timer(func2)
def func2(a):
    print('in func2 and get a:%s'%(a))
    return 'fun2 over'
func2('aaaaaa')
print(func2('aaaaaa'))

4.3 給裝飾器帶參數(shù)

def outer(flag):
    def timer(func):
        def inner(*args,**kwargs):
            if flag:
                print('''執(zhí)行函數(shù)之前要做的''')
            re = func(*args,**kwargs)
            if flag:
                print('''執(zhí)行函數(shù)之后要做的''')
            return re
        return inner
    return timer
# 下面的裝飾過程
# 1. 調(diào)用outer(False)
# 2. 將步驟1得到的返回值,即timer返回, 然后timer(func),這里的func指向定義的func函數(shù)
# 3. 將timer(func)的結果返回,即inner
# 4. 讓func = inner,即func現(xiàn)在指向inner
@outer(False)    
def func():   
    print(111)
func()

調(diào)用時候的func()可以理解為:func() ====> outer(Flase)(func)()

4.4裝飾器的功能:

在不修改原函數(shù)及其調(diào)用方式的情況下對原函數(shù)功能進行擴展。

4.5.裝飾器應用場景:

(1)引入日志

(2)函數(shù)執(zhí)行時間統(tǒng)計

(3)執(zhí)行函數(shù)前預備處理

(4)執(zhí)行函數(shù)后清理功能

(5)權限校驗等場景

(6)緩存

4.6 functools的應用

正常我們情況下查看函數(shù)的一些信息的方法在此處都會失效

def outer(func):
    def inner(*args,**kwargs):
        """hello world"""
        return func(*args,**kwargs)
    return inner
@outer
def index():
    '''你好,世界'''
    print('hello world!')
print("函數(shù)注釋:%s" % index.__doc__)    #查看函數(shù)注釋的方法
print("函數(shù)名:%s" % index.__name__)   #查看函數(shù)名的方法

上述代碼返回的結果是:

在這里插入圖片描述

很顯然,這不是我們需要的結果。我們希望得到的是被裝飾的函數(shù)的函數(shù)名和注釋。

functools的wraps能夠?qū)⒃械暮瘮?shù)名返回,需要使用functools.wraps在裝飾器中的函數(shù)上把傳進來的這個函數(shù)進行一個包裹,這樣就不會丟失原來的函數(shù)的__name__等屬性.

from functools import wraps
def outer(func):
    @wraps(func)
    def inner(*args,**kwargs):
        """hello world"""
        return func(*args,**kwargs)
    return inner
@outer
def index():
    '''你好,世界'''
    print('hello world!')
print("函數(shù)注釋:%s" % index.__doc__)    #查看函數(shù)注釋的方法
print("函數(shù)名:%s" % index.__name__)   #查看函數(shù)名的方法

運行結果為:

在這里插入圖片描述

5.類裝飾器

class Test(object):
    def __init__(self, func):
        print("---初始化---")
        print("func name is %s"%func.__name__)
        self.__func = func
    def __call__(self):
        print("---裝飾器中的功能---")
        self.__func()
#說明:
#1. 當用Test來裝作裝飾器對test函數(shù)進行裝飾的時候,首先會創(chuàng)建Test的實例對象
#   并且會把test這個函數(shù)名當做參數(shù)傳遞到__init__方法中
#   即在__init__方法中的屬性__func指向了test指向的函數(shù)
#
#2. test指向了用Test創(chuàng)建出來的實例對象
#
#3. 當在使用test()進行調(diào)用時,就相當于讓這個對象(),因此會調(diào)用這個對象的__call__方法
#
#4. 為了能夠在__call__方法中調(diào)用原來test指向的函數(shù)體,所以在__init__方法中就需要一個實例屬性來保存這個函數(shù)體的引用
#   所以才有了self.__func = func這句代碼,從而在調(diào)用__call__方法中能夠調(diào)用到test之前的函數(shù)體
@Test
def test():
    print("----test---")
test()
showpy()#如果把這句話注釋,重新運行程序,依然會看到"--初始化--"

運行結果如下:

---初始化---
func name is test
---裝飾器中的功能---
----test---

到此這篇關于python必學知識之裝飾器詳解的文章就介紹到這了,更多相關python裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Python爬蟲框架scrapy實現(xiàn)downloader_middleware設置proxy代理功能示例

    Python爬蟲框架scrapy實現(xiàn)downloader_middleware設置proxy代理功能示例

    這篇文章主要介紹了Python爬蟲框架scrapy實現(xiàn)downloader_middleware設置proxy代理功能,結合實例形式分析了scrapy框架proxy代理設置技巧與相關問題注意事項,需要的朋友可以參考下
    2018-08-08
  • 如何使用Python的Requests包實現(xiàn)模擬登陸

    如何使用Python的Requests包實現(xiàn)模擬登陸

    這篇文章主要為大家詳細介紹了使用Python的Requests包模擬登陸,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • TensorFlow2.0使用keras訓練模型的實現(xiàn)

    TensorFlow2.0使用keras訓練模型的實現(xiàn)

    這篇文章主要介紹了TensorFlow2.0使用keras訓練模型的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-02-02
  • python解析中國天氣網(wǎng)的天氣數(shù)據(jù)

    python解析中國天氣網(wǎng)的天氣數(shù)據(jù)

    最近學習python 感覺這門腳本語言十分靈活 而且功能十分強大 尤其是他re庫用于正則匹配十分強大,寫了個例子解析中國天氣網(wǎng)
    2014-03-03
  • 深度Q網(wǎng)絡DQN(Deep Q-Network)強化學習的原理與實戰(zhàn)

    深度Q網(wǎng)絡DQN(Deep Q-Network)強化學習的原理與實戰(zhàn)

    深度Q學習將深度神經(jīng)網(wǎng)絡與強化學習相結合,解決了傳統(tǒng)Q學習在高維狀態(tài)空間下的局限性,通過經(jīng)驗回放和目標網(wǎng)絡等技術,DQN能夠在復雜環(huán)境中學習有效的策略,本文通過CartPole環(huán)境的完整實現(xiàn),展示了DQN的核心思想和實現(xiàn)細節(jié)
    2025-04-04
  • 使用go和python遞歸刪除.ds store文件的方法

    使用go和python遞歸刪除.ds store文件的方法

    使用python和go遞歸刪除.DS_Store文件,.DS_Store (英文全稱 Desktop Services Store)是一種由蘋果公司的Mac OS X操作系統(tǒng)所創(chuàng)造的隱藏文件,目的在于存貯文件夾的自定義屬性
    2014-01-01
  • 利用Python刪除電腦中重復文件的方法

    利用Python刪除電腦中重復文件的方法

    這篇文章主要介紹了利用Python刪除電腦中的重復文件,下文我們來分享解決電腦中文件重復的情況的一個方法,需要的朋友可以參考一下,希望對大家日常問題解決有所幫助
    2022-05-05
  • 詳解如何使用opencv實現(xiàn)圖片相似度檢測

    詳解如何使用opencv實現(xiàn)圖片相似度檢測

    這篇文章主要為大家詳細介紹了如何使用opencv實現(xiàn)圖片相似度檢測,文中的示例代碼講解詳細,對于我們學習人工智能有一定的幫助,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-12-12
  • python超詳細實現(xiàn)完整學生成績管理系統(tǒng)

    python超詳細實現(xiàn)完整學生成績管理系統(tǒng)

    讀萬卷書不如行萬里路,只學書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java實現(xiàn)一個完整版學生成績管理系統(tǒng),大家可以在過程中查缺補漏,提升水平
    2022-03-03
  • pandas提取數(shù)據(jù)的6種方法匯總

    pandas提取數(shù)據(jù)的6種方法匯總

    這篇文章主要介紹了pandas提取數(shù)據(jù)的6種方法匯總,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08

最新評論