python裝飾器詳解(三)---裝飾器高階用法
1. 在裝飾器函式裡傳入引數
def a_decorator_passing_arguments(function_to_decorate):
def a_wrapper_accepting_arguments(arg1,arg2):
print("Igot args Look!",arg1,arg2)
function_to_decorate(arg1,arg2)
return a_wrapper_accepting_arguments
當你呼叫裝飾器返回的函式時,也就呼叫了包裝器,把引數傳入包裝器裡,它將把引數傳遞給被裝飾的函式裡。
@a_decorator_passing_arguments
print("Myname is ",first_name,last_name)
print_full_name("Peter","Venkman")
輸出
I got args Look! Peter Venkman
My name is Peter Venkman
但是上述裝飾器限制了被裝飾的方法只能是兩個引數,下面用用*args,**kwargs實現通用版裝飾器。
def a_decorator_passing_arbitrary_arguments(function_to_decorate): #包裝器接收所有引數 def a_wrapper_accepting_arbitrary_arguments(*args,**kwargs):print("Do I have args?") print(args) print(kwargs) # 現在把*args,**kwargs解包 # 如果你不明白什麼是解包的話,請查閱: # http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/ function_to_decorate(*args,**kwargs)return a_wrapper_accepting_arbitrary_arguments
(1)無引數函式呼叫裝飾器
@a_decorator_passing_arbitrary_arguments
def function_with_no_argument():
print("Pythonis cool,no argument here")
執行
function_with_no_argument()
輸出
#Do I have args?:
#()
#{}
#Pythonis cool, no argument here.
(2)有引數函式呼叫裝飾器
@a_decorator_passing_arbitrary_arguments
def function_with_arguments(a,b,c):
print(a,b,c)
執行
function_with_arguments(1,2,3)
輸出
#Do I have args?:
#(1, 2, 3)
#{}
#1 2 3
(3)有關鍵字引數函式呼叫裝飾器
@a_decorator_passing_arbitrary_arguments
def function_with_named_arguments(a,b,c,platpus= "whynot?"):
print("Do%s ,%s and %s like platpus? %s" %(a,b,c,platpus))
執行
function_with_named_arguments("bill","linus","steve",platpus="indeed!")
輸出
#Do I have args ? :
#('Bill', 'Linus', 'Steve')
#{'platypus': 'Indeed!'}
#Do Bill, Linus and Steve like platypus?Indeed!
(4)在類的方法中呼叫
在Python裡方法和函式幾乎一樣.唯一的區別就是方法的第一個引數是一個當前物件的(self), 也就是說你可以用同樣的方式來裝飾方法!只要記得把self加進去。
def method_friendly_decorator(method_to_decorate):
def wrapper(self,lie):
lie = lie -3
# returnmethod_to_decorate(self,lie) 也可以method_to_decorate(self,lie)
return wrapper
classLucy(object):
def __init__(self):
self.age= 32
@method_friendly_decorator
def sayYourAge(self,lie):
print("Iam %s, what did you think"%(self.age+lie))
執行
l = Lucy()
l.sayYourAge(-3)
輸出
I am 26,what did you think
用通用版裝飾器
class Mary(object): def __init__(self): self.age = 31 @a_decorator_passing_arbitrary_arguments def sayYourAge(self,lie=-3): #可以加入預設值 print("I am %s,what did you think"%(self.age + lie))
執行
m = Mary()
m.sayYourAge()
輸出
# Do I have args?:
#(<__main__.Mary object at0xb7d303ac>,) ####就一個self引數
#{}
#I am 28, what did you think?