大家好啊~我是Willis,今天要來介紹Decorator(裝飾器)的進階用法唷 ~ (ᗒᗨᗕ)/
其實裝飾器只是一種呼叫函數的方式,只是如果用函數的呼叫方式的話會使程式碼過於繁瑣,讓可讀性大大降低,那原本的呼叫方式是怎麼樣呢 ? 一起來看看吧 ~
app.py
import random
def odd_fun(fun):
def wrapper():
num = fun()
if (int)(num) % 2 != 0:
print("{}判斷為奇數".format(num))
else:
print("{}判斷為偶數".format(num))
return wrapper
def random_fun():
input_num = random.randint(1, 10)
return input_num
odd_fun(random_fun)() # 使用函數的呼叫方式
8判斷為偶數
5判斷為奇數
今天如果我一次呼叫很多個裝飾器會發生甚麼事呢 ?
app.py
def decorator_1(fun):
def wrappper(*args):
print("裝飾器1開始")
fun(*args)
print("裝飾器1結束")
return wrappper
def decorator_2(fun):
def wrappper(*args):
print("裝飾器2開始")
fun(*args)
print("裝飾器2結束")
return wrappper
def decorator_3(fun):
def wrappper(*args):
print("裝飾器3開始")
fun(*args)
print("裝飾器3結束")
return wrappper
@decorator_1
@decorator_2
@decorator_3
def function(*args):
print("我是函數 傳入參數為:{}".format(*args))
function(123)
裝飾器1開始
裝飾器2開始
裝飾器3開始
我是函數 傳入參數為:123
裝飾器3結束
裝飾器2結束
裝飾器1結束
app.py
def decorator_1(fun):
def wrappper(*args):
print("裝飾器1開始")
fun(*args)
print("裝飾器1結束")
return wrappper
def decorator_2(fun):
def wrappper(*args):
print("裝飾器2開始")
fun(*args)
print("裝飾器2結束")
return wrappper
def decorator_3(fun):
def wrappper(*args):
print("裝飾器3開始")
fun(*args)
print("裝飾器3結束")
return wrappper
def function(*args):
print("我是函數 傳入參數為:{}".format(*args))
decorator_1(decorator_2(decorator_3(function)))(123) # 這是甚麼鬼@@
裝飾器1開始
裝飾器2開始
裝飾器3開始
我是函數 傳入參數為:123
裝飾器3結束
裝飾器2結束
裝飾器1結束
看完原本的呼叫方式後,知道裝飾器的厲害了吧 ~
裝飾器還有一個厲害的地方,就是它可以傳遞參數。
def 裝飾器工廠名稱(參數名稱)
def 裝飾器名稱(函數名稱):
def wrapper():
...
return wrapper
return 裝飾器名稱
app.py
import random
def factory(num):
def odd_fun(fun):
def wrapper():
if (int)(num) % 2 != 0:
print("{}判斷為奇數".format(num))
else:
print("{}判斷為偶數".format(num))
fun()
return wrapper
return odd_fun
@factory(random.randint(1, 10)) # 傳入參數:隨機亂數1 ~ 10
def function():
print("我是函數")
function()
8判斷為偶數
我是函數
除了Fnction能使用裝飾器以外,其實Class也可以使用裝飾器。
app.py
class Decorateclass():
def __init__(self, fun):
self.fun = fun
def __call__(self, *args, **kwargs):
print("我是class")
self.fun()
@Decorateclass
def function():
print('我是函數')
if __name__ == '__main__':
function()
我是class
我是函數
app.py
class Decorateclass():
def __init__(self, num):
self.num = num
def __call__(self, fun):
def wrapper(*args):
print("我是class 傳入參數為:{}".format(self.num))
fun()
return wrapper
@Decorateclass(123)
def function():
print('我是函數')
if __name__ == '__main__':
function()
我是class 傳入參數為:123
我是函數
https://blog.typeart.cc/%E5%BF%AB%E9%80%9F%E7%90%86%E8%A7%A3%E4%B8%A6%E4%BD%BF%E7%94%A8Python%20Decorator/#Class-based-Decorator
https://www.maxlist.xyz/2019/12/07/python-decorator/
https://www.youtube.com/watch?v=F4hWr87ZcSc&ab_channel=%E5%BD%AD%E5%BD%AD%E7%9A%84%E8%AA%B2%E7%A8%8B
關於Decorator(裝飾器)的介紹就到這裡囉 ~ 大家掰掰 ヽ(✿゚▽゚)ノ