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?

你可能感兴趣的:(python)