1. 程式人生 > 其它 >@函式裝飾器

@函式裝飾器

裝飾器

  • 假設用funcA函式裝飾器去裝飾funcB函式
# 裝飾器函式
def funcA(fc):
  print('this is funcA')
  # 執行傳入的fc引數
  fc()
  return fc

@funcA
def funcB():
  print('this is funcB')
funcB()

output:
this is funcA
this is funcB
this is funcB

以上內容等價於:

# 裝飾器函式
def funcA(fc):
  print('this is funcA')
  # 執行傳入的fc引數
  fc()
  return fc

def funcB():
  print('this is funcB')
funcB = funcA(funcB)

即:funcB作為引數傳給裝飾器函式funcAfuncA的執行返回值賦值給funcB

由此可見,被“裝飾”的函式取決於裝飾器的返回值

實際上,所謂函式裝飾器,就是通過裝飾器函式,在不改變原函式的前提下,對函式的功能進行合理擴充。

帶參的裝飾器

  • funcB沒有引數時,直接將funcB作為引數傳給裝飾器funcA
  • funcB有引數時,可在裝飾器funcA中巢狀一個函式,該函式的引數個數與funcB相同。
  • Example:
def funcA(fc):
  def subFunc(input):
    print('funcA-subFunc:{}'.format(input))
  return subFunc

@funcA
def funcB(input):
  print('funcB:{}'.format(input))
funcB('函式裝飾器')

output:
funcA-subFunc:函式裝飾器

顯然,在程式中呼叫的是funcB函式,但實際執行的是被裝飾器巢狀的subFunc函式。
以上程式碼等價於:

def funcA(fc):
  def subFunc(input):
    print('funcA-subFunc:{}'.format(input))
  return subFunc

def funcB(input):
  print('funcB:{}'.format(input))
func = funcA(funcB)
func('函式裝飾器')

output:
funcA-subFunc:函式裝飾器

以上示例為函式只有一個引數的情況,若一個裝飾器用於多個函式,該如何定義呢?

*args**kwargs 表示可以接受任意數量與型別的引數,可將其作為裝飾器巢狀函式的引數。例如:

def funcA(fc):
  def subFunc(*args, **kwargs):
    print('funcA:{}'.format(*args, **kwargs))
  return subFunc
@funcA
def funcB(input):
  print('funcB:{}'.format(input))

@funcA
def funcC(input):
  print('funcC:{}'.format(input))
# 字串
funcB('funcB')
# 整數
funcC(1)

outputs:
funcA:funcB
funcA:1