注:讀本文章前請先了解閉包或者讀作者的python閉包附上連結python閉包
python 函數裝飾器
函數裝飾器 decorators
- 定義:在不改變原函數的調用以及内部代碼的情況下,為其添加新功能的函數.
- 文法:
def 函數裝飾器名稱(func): def 内嵌函數(*args,**kwargs) 需要添加的新功能 return func(*args, **kwargs) return wrapper @ 函數裝飾器名稱 def 原函數名稱(參數): 函數體 原函數(參數)
-
本質: 使用“@函數裝飾器名稱”修飾原函數,等同于建立與原函數名稱相同的變量,關聯内嵌函數;故調用原函數時執行内嵌函數。
原函數名稱 = 函數裝飾器名稱(原函數名稱)
-
裝飾器鍊:
一個函數可以被多個裝飾器修飾,執行順序為從近到遠。
函數裝飾器的應用 :
需求:在兩個方法實作的功能基礎上,增加新功能(列印方法名稱)
def say_hello():
print("hello")
def say_goodbye():
print("goodbye")
say_hello()
say_goodbye()
# 輸出
'''
hello
goodbye
'''
方案1
缺點:代碼重複.
解決:提取列印方法名稱的功能
def say_hello():
print(say_hello.__name__)
print("hello")
def say_goodbye():
print(say_goodbye.__name__)
print("goodbye")
say_hello()
say_goodbye()
# 輸出
'''
say_hello
hello
say_goodbye
goodbye
'''
方案2
缺點:在兩個已有功能的内部,增加新功能,代碼可讀性差.
def print_func_name(func):
print(func.__name__)
def say_hello():
# print(say_hello.__name__)
print_func_name(say_hello)
print("hello")
def say_goodbye():
# print(say_goodbye.__name__)
print_func_name(say_goodbye)
print("goodbye")
say_hello()
say_goodbye()
# 輸出:
'''
say_hello
hello
say_goodbye
goodbye
'''
方案示例(略…上正題)
使用函數裝飾器
包裝器适應所有的舊功能參數
定義者負責包裝函數,調用者隻負責調用
# 定義函數裝飾器
def print_func_name(func):
# 包裝新舊功能
def wrapper(*args, **kwargs):
# 增加的新功能
print(func.__name__)
# 舊功能
return func(*args, **kwargs)
return wrapper # 傳回包裝器
# 使用函數裝飾器
@print_func_name # say_hello = print_func_name(say_hello)
def say_hello(name):
print(name, "hello")
return "哈哈"
@print_func_name
def say_goodbye(name, age):
print(age, name, "goodbye")
# # ---------以上是定義者--以下是調用者-----------------
print(say_hello("滅霸"))
say_goodbye("北極星女孩", 25)
# 輸出:
'''
say_hello
滅霸 hello
哈哈
say_goodbye
25 北極星女孩 goodbye
'''