裝飾器本質上是一個python函數或者類,它可以讓其他函數或者類在不需要做任何代碼修改的前提下增加額外的功能,裝飾器的返回值也是一個函數/類對象。
使用場景:插入日志、性能測試、事務處理、緩存、權限校驗等場景
優點:有了裝飾器,我們就可以抽離出大量函數功能本身無關的雷同代碼到裝飾器中並繼續重用,概括的講,裝飾器的作用及時為了已經存在的對象添加額外的功能。
def log(func):
def wrapper(*args,**kwargs):
print("{}的日志".formate(func.__name__))
return func(*args,**kwargs)
return wrapper
@log
def test_func():
pass
python中的函數可以像參數一樣傳遞給另外一個函數。
def func1():
print("func1被執行~")
def func2(func):
func()
func2(func1) # func1被執行~
import logging
logging.warning(logging message)
import logging
def func1():
print("func1被執行~")
logging.warning("func1的運行日志~")
def func2(func):
func()
func2(func1)
def func1():
print("func1被執行~")
def func2():
print("func2被執行~")
def func3():
print("func3被執行~")
def func_log(func):
logging.warning('''{}正在運行~~'''.format(func.__name__))
func()
func_log(func1)
func_log(func2)
func_log(func3)
通過上面的例子我們發現,想要達到執行函數並且打印日志的功能,我們就需要通過調用日志函數來達到我們的目的,很難單純的通過函數名去執行函數和打印日志,此時裝飾器的好處就體現出來了…
# 裝飾器的調用
def func_logging(func):
def wrapper():
print("{}的日志".format(func.__name__))
func()
return wrapper
@func_logging
def func1():
print("func1函數被執行")
func1()
# 裝飾器調用原理
def func_logging(func): # func--->func1
def wrapper():
print("{}的日志".format(func.__name__))
func()
return wrapper # 函數
def func1():
print("func1函數被執行")
func1 = func_logging(func1)
func1()
# 被裝飾的函數帶有參數(有的帶參數,有的不帶參數,有的參數個數不確定)
def func_logging(func):
def wrapper(*args, **kwargs):
print("{}的日志".format(func.__name__))
func(*args, **kwargs)
return wrapper
@func_logging
def func1(name):
print("func1函數被執行",name)
@func_logging
def func2(name, age):
print("func2函數被執行",name, age)
@func_logging
def func3():
print("func3函數被執行")
func1('func1')
func2("func2",18)
func3()