python中的装饰器(以及多个装饰器详细执行过程)
裝飾器
1.如果要增強一個函數(shù)的功能,但又不希望更改原函數(shù)中的代碼,這種在代碼運行期間動態(tài)增加功能的機制被稱為裝飾器
? 【Decorator】
2.?本質:實際上就是一個閉包,只不過被裝飾的函數(shù)需要作為參數(shù)傳遞給閉包
3.裝飾器的書寫格式:給閉包的外部函數(shù)設置一個參數(shù)【需要被裝飾的函數(shù)】,
? 外部函數(shù)的返回值是內部函數(shù)的引用【裝飾的結果】,這種函數(shù)被稱為高階函數(shù)
4.裝飾器的好處:
? ? ①?不用修改源代碼就可以更改函數(shù)
? ? ②?提高代碼的維護性
? ? ③?提高代碼的復用性
5.應用場景:
? ? ①?引入日志
? ? ②?統(tǒng)計函數(shù)的執(zhí)行時間?
? ? ③權限校驗
? ? ④緩存
?
?裝飾器的使用
1. 簡單的裝飾器
# 1. 簡單的裝飾器 def test():print("人生苦短,我用python")# 裝飾器的書寫步驟 # 1.書寫閉包 # 2.傳參:給outter設置參數(shù),該參數(shù)表示需要被增加的功能函數(shù) def outter(func):def inner():# 3.調用原函數(shù)func()# 4.增加新功能print("PYTHON")# 5.將裝飾之后的結果返回【方便在函數(shù)外面調用】return inner# 6.然后進行調用 f = outter(test) f()""" 裝飾器的執(zhí)行順序:1.f = outter(test),調用outter函數(shù),func = test , f = inner2.f(),調用inner函數(shù)3.func(), 調用test原函數(shù) """2.有參數(shù)的裝飾器
# 2.有參數(shù)的裝飾器def getAge(age):print(age)# 需求:當傳入的年齡為負數(shù)時,打印相反數(shù) def outter2(func):def inner2(num):if num < 0:num = abs(num)func(num)return inner2f2 = outter2(getAge) # func = getAge f2 = inner2 f2(-31) """ 通過上述的操作,將邊界檢查的操作隔離到單獨的函數(shù)中,并沒有修改原函數(shù)給裝飾器的內部函數(shù)是否需要設置參數(shù),如果原函數(shù)有參數(shù),并且在裝飾器中的inner中需要對原函數(shù)的參數(shù)運算則建議給inner設置參數(shù),該參數(shù)需要和原函數(shù)的參數(shù)有關 """3.使用符號@將裝飾器應用于函數(shù)? ? ? ? ?
? ?@的作用:簡化裝飾器的調用? ? ? ? ? @裝飾器名稱? ? 應用于被裝飾的函數(shù)聲明的前面
? ? ?#?注意:使用@使用裝飾器,則裝飾器必須先存在,然后才能使用它,即就是要先有裝飾器函數(shù)
? ?使用@應用裝飾器,則調用裝飾器只需要通過原函數(shù)名調用
# 3.使用符號@將裝飾器應用于函數(shù)? ? ? ? ? @的作用:簡化裝飾器的調用 def outter3(func):def inner3(num):if num < 0:num = abs(num)func(num)return inner3# 使用@應用裝飾器 @outter3 def getAge(age):print(age)# 調用 getAge(-69)""" @裝飾器的執(zhí)行的順序1.@outter3: 相當于f = outter3(getAge),完成了func = getAge,f = inner3也就是getAge = inner32.getAge(-69) : 相當于【f(-69)】,調用inner3 """4.一個裝飾器修改多個函數(shù)
? ?①多個函數(shù)都沒有參數(shù)
def outter4(func):def inner4():func()print("裝飾器中的新功能")return inner4@outter4 def show1():print("show-1")@outter4 def show2():print("show-2")@outter4 def show3():print("show-3")show1() show2() show3()?運行結果:
?②多個函數(shù)擁有不同的參數(shù)
def outter4(func):def inner4(*args, **kwargs): # 使用不定長參數(shù)func(*args, **kwargs)print("裝飾器中的新功能")return inner4@outter4 def show1():print("show-1")print("show1無參數(shù)")@outter4 def show2(a, b):print("show-2")print('show2中的參數(shù):', a, b)@outter4 def show3(num1, num2, num3):print("show-3")print('show3中的參數(shù):', num1, num2, num3)show1() show2(2, 3) show3(4, 5, 6)?打印結果:
5.多個裝飾器修改一個函數(shù)
? ? 給同一個函數(shù)同時增加了多個新的功能
def outter_1(func1):def inner_1(*args, **kwargs): # 使用不定長參數(shù)print("inner_1內容")func1(*args, **kwargs)print("第一個裝飾器-----1")return inner_1def outter_2(func2):def inner_2(*args, **kwargs): # 使用不定長參數(shù)print("inner_2內容")func2(*args, **kwargs)print("第二個裝飾器-----2")return inner_2def outter_3(func3):def inner_3(*args, **kwargs): # 使用不定長參數(shù)print("inner_3內容")func3(*args, **kwargs)print("第三個裝飾器-----3")return inner_3@outter_1 @outter_2 @outter_3 def show_1():print("show_1")show_1() """多個裝飾器加載的順序1.@outter_3:show_1原函數(shù)-->outter_3-->func3 = show_1原函數(shù)-->show_1指向了inner_32.@outter_2:inner_3-->outter_2-->func2 = inner_3-->show_1指向了inner_23.@outter_1: inner_2-->outter_1-->func1 = inner_2-->show_1最終指向了inner_1所以多個裝飾器的執(zhí)行調用過程show_1()-->inner_1()-->func1()-->inner_2()-->func2()-->inner_3()-->func3()-->show_1()原 """?運行過程:
?
""" 結論:如果多個裝飾器修飾同一個函數(shù),傳參: 從下往上【就近原則】代碼的執(zhí)行順序: 從上往下 """?
總結
以上是生活随笔為你收集整理的python中的装饰器(以及多个装饰器详细执行过程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中的列表生成式
- 下一篇: Python中的函数递归