簡單的說,裝飾器就是 函數的函數。
正常來說,我們定義一個函數的函數通常是這樣的:
# 定義一個函數的函數
def Func4func(func):
def printf(input): # 由於Func4func的return是這個printf,所以之後被裝飾後的func的輸入參數是 input。
return func() + ' in Func4func'+' with [input]:\t' + input
return printf
# 定義一個函數
def func():
meg = 'i am a function'
print(meg)
return meg
# 用Func4func來裝飾func,注意是傳入函數func而不是函數運行後結果func()
decorated_func = Func4func(func)
# 裝飾後的函數實際上是printf(input)
print(decorated_func('haha')) # 'haha'實際上是 Func4func中的 printf()的input。
輸出結果:
i am a function
i am a function in Func4func with [input]: haha
裝飾器使用 @
標識符可以把上面的調用簡化,簡化後就變成了這樣:
# 定義一個函數的函數
def Func4func(func):
def printf(input): # 由於Func4func的return是這個printf,所以之後被裝飾後的func的輸入參數是 input。
return func() + ' in Func4func'+' with [input]:\t' + input
return printf
# 用Func4func來裝飾func
@Func4func
def func(): # 定義一個函數
meg = 'i am a function'
print(meg)
return meg
# func在被Func4func裝飾之後,實際上等價於上面的decorated_func,所以現在的func實際上是Func4func(func),因此需要傳入input參數。
print(func('haha')) # 'haha'實際上是 Func4func中的 printf()的input。
輸出結果:
i am a function
i am a function in Func4func with [input]: haha
更進一步,裝飾器函數(函數的函數)也可以定義它的參數:
# 定義一個函數的函數,這個函數帶參數。
def Func4func_wi_parameter(para): # 在原來的Func4func外面再嵌套一層Func4func_wi_parameter(para),其中para就是參數。
def Func4func(func):
def printf(input): # 由於Func4func的return是這個printf,所以之後被裝飾後的func的輸入參數是 input。
return func() + ' in Func4func'+' with [input]:\t' + input + ' and [Para]:\t'+para
return printf
return Func4func # 返回函數Func4func而不是函數運行後的結果Func4func()
# Func4func_wi_parameter(para)傳入參數後,返回值是Func4func,所以實際上還是用Func4func來裝飾func
@Func4func_wi_parameter('parameter666666')
def func(): # 定義一個函數
meg = 'i am a function'
print(meg)
return meg
print(func('haha')) # 'haha'實際上是 Func4func中的 printf()的input。
輸出結果:
i am a function
i am a function in Func4func with [input]: haha and [Para]: parameter666666
如果func
是帶參數的,也可以通過下面方法輸入參數:
# 定義一個函數的函數,這個函數帶參數。
def Func4func_wi_parameter(para): # 在原來的Func4func外面再嵌套一層Func4func_wi_parameter(para),其中para就是參數。
def Func4func(func):
def printf(meg:str, input:str): # 由於Func4func的return是這個printf,所以之後被裝飾後的func的輸入參數是 input。
return func(meg) + ' in Func4func'+' with [input]:\t' + input + ' and [Para]:\t'+para
return printf
return Func4func # 返回函數Func4func而不是函數運行後的結果Func4func()
# Func4func_wi_parameter(para)傳入參數後,返回值是Func4func,所以實際上還是用Func4func來裝飾func
@Func4func_wi_parameter('parameter666666')
def func(meg:str='???'): # 定義一個函數
print(meg)
return meg
print(func('i am a func','haha')) # 'haha'實際上是 Func4func中的 printf()的input。
輸出結果:
i am a function
i am a function in Func4func with [input]: haha and [Para]: parameter666666