簡單來說,裝飾器的作用就是爲已經存在的函數或對象添加額外的功能。
先來定義一個簡單的函數
def say_hello():
print("hello!")
那麼我們現在想實現這樣一個功能:打印出這個函數的名稱。但是又不能修改這個函數的代碼,(遵循了開閉原則),這個時候裝飾器就要登場了
def print_name(func):
print("[func_name]: %s ()" % func.__name__)
return func()
這就是一個簡單的裝飾器,他所具有的功能就是在被他裝飾的函數會打印"[fun_name]: %s ()" % func.__name__,
裝飾器的使用就是在需要被裝飾的函數的上面一行加上@(語法糖),後面是寫好的裝飾器名稱
@print_name
def say_hello():
print("hello!")
say_hello()
==============輸出=============
[func_name]: say_hello ()
hello!
下面解決一下裝飾有參數的函數的裝飾器
先寫一個帶參數的函數
def say(something):
print("hello {}!".format(something))
當被裝飾的函數需要傳遞參數,裝飾器如下
def print_name(func):
def wrapper(something1): # 指定一毛一樣的參數
print("[name]: {}()".format(func.__name__))
return func(something1)
return wrapper # 返回包裝過函數
裝飾器效果如下
@print_name
def say(something):
print("hello {}!".format(something))
say("wuhan fighting!!")
================輸出==============
[name]: say()
hello wuhan fighting!
再進一步,裝飾器需要傳參呢
# ============帶參數的裝飾器==============
# 這層傳入裝飾器的參數
def logging(level):
# 這層傳入要裝飾的函數
def wrapper(func):
# 這層傳入要裝飾的函數的參數
def inner_wrapper(*args, **kwargs):
print("[{level}]: enter function {func}()".format(
level=level,
func=func.__name__))
return func(*args, **kwargs)
return inner_wrapper
return wrapper
看效果
@logging(level='INFO')
def say(something):
print("say {}!".format(something))
say('武漢加油!!')
================輸出==================
[INFO]: enter function say()
say 武漢加油!!!
武漢加油!!中國加油!!!