1. 程式人生 > >python裝飾器詳解(三)---裝飾器高階用法

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

def print_full_name(first_name,last_name):
   
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?