Source From Here
Preface
Python Decorator 可以以 function 與 class 實作出來,且有無參數的寫法也會因此不一樣,以下記錄了從 Stack Overflow 學習來的 decorator 寫法 {function, class} X {with, without} arguments = 4 種.
Decorator Function
沒有參數的 Function 版本
使用 closure 去處理 function:
Execution output:
有參數的 Decorator Function
需要多一層的 outter function 來傳入參數:
Execution output:
Decorator Class
沒有參數版本的 Decorator Class
Python 會將被修飾的 function 傳入 __init__,這時就將它存入到 decorator 的 data member self.f 。另外再直接覆寫 __call__ ,然後在呼叫 self.f 的前後作額外的修飾動作。這裡的 __call__ 的 signature ,就是跟 被修飾的 function 一樣,所以就加上動態的 *args, 跟 **kargs 就可以完整 delegate了。
Execution output:
帶有參數版本的 Decorator Class
當有參數版本的 decorator class 在修飾 function 時,function 就不會像沒有參數版本的 decorator class 一樣,會將 function 傳入 __init__,而是會傳入 decorator 的參數。function 本體則是會在 __call__ 中被傳入,這是一個比較不一樣的地方。
Execution output:
Preface
Python Decorator 可以以 function 與 class 實作出來,且有無參數的寫法也會因此不一樣,以下記錄了從 Stack Overflow 學習來的 decorator 寫法 {function, class} X {with, without} arguments = 4 種.
Decorator Function
沒有參數的 Function 版本
使用 closure 去處理 function:
- def decorateApple(f):
- print "=== Enter decorator with %s" % (f)
- def d_f(*args, **kargs):
- print("=== apple before call")
- result = f(*args, **kargs)
- print("=== apple after call")
- return result
- print "=== Exit decorator"
- return d_f
- @decorateApple
- def print_hello(name):
- print("Hello %s." % (name))
- print_hello('John')
有參數的 Decorator Function
需要多一層的 outter function 來傳入參數:
- def decorateApple(*dargs, **dkargs):
- print "=== Enter decorator"
- for a in dargs:
- print "==== Arg=%s" % a
- def outer_d_f(f):
- print "===== Enter outer_d_f"
- def d_f(*args, **kargs):
- print("======= apple before call")
- result = f(*args, **kargs)
- print("======= apple after call")
- return result
- print "===== Exit outer_d_f"
- return d_f
- print "=== Exit decorator"
- return outer_d_f
- @decorateApple('banana')
- def print_hello(name):
- print("Hello %s." % (name))
- print_hello('John')
Decorator Class
沒有參數版本的 Decorator Class
Python 會將被修飾的 function 傳入 __init__,這時就將它存入到 decorator 的 data member self.f 。另外再直接覆寫 __call__ ,然後在呼叫 self.f 的前後作額外的修飾動作。這裡的 __call__ 的 signature ,就是跟 被修飾的 function 一樣,所以就加上動態的 *args, 跟 **kargs 就可以完整 delegate了。
- #!/usr/bin/env python
- class decorateAppleClass(object):
- def __init__(self, f):
- self.f = f
- def __call__(self, *args, **kargs):
- print("===== apple before call")
- result = self.f(*args, **kargs)
- print("===== apple after call")
- return result
- @decorateAppleClass
- def print_hello4(name):
- print("Hello %s." % (name))
- print_hello4('John')
帶有參數版本的 Decorator Class
當有參數版本的 decorator class 在修飾 function 時,function 就不會像沒有參數版本的 decorator class 一樣,會將 function 傳入 __init__,而是會傳入 decorator 的參數。function 本體則是會在 __call__ 中被傳入,這是一個比較不一樣的地方。
- #!/usr/bin/env python
- class decorateAppleClass(object):
- def __init__(self, *dargs, **dkw):
- print("===== Enter decorator __init__")
- for a in dargs:
- print("-----> Arg=%s" % (a))
- def __call__(self, f):
- def d_f(*args, **kargs):
- print("===== apple before call")
- result = f(*args, **kargs)
- print("===== apple after call")
- return result
- return d_f
- @decorateAppleClass('banana')
- def print_hello4(name):
- print("Hello %s." % (name))
- print_hello4('John')
沒有留言:
張貼留言