多个装饰器装饰一个函数
# def debug(func): # # def wrapper(): # # print ("[DEBUG]: enter {}()".format(func.__name__)) # # return func() # # return wrapper # # @debug # # def say_hello(): # # print("hello!") # say_hello() # 添加功能并保持原函数名不变 #这是最简单的装饰器,但是有一个问题,如果被装饰的函数需要传入参数,那么这个装饰器就坏了。因为返回的函数并不能接受参数 #可以指定装饰器函数wrapper接受和原函数一样的参数,比如: # def debug(func): # def wrapper(something): # 指定一毛一样的参数 # print("[DEBUG]: enter {}()".format(func.__name__)) # return func(something) # return wrapper # 返回包装过函数 # # @debug # def say(something): # print ("hello {}!".format(something)) # say('今天是个好日子') # def debug(func): # # def wrapper(*args, **kwargs): # 指定宇宙无敌参数 # print ("[DEBUG]: enter {}()".format(func.__name__)) # print ('Prepare and say...',) # return func(*args, **kwargs) # return wrapper # 返回 # # @debug # def say(something): # print ("hello {}!".format(something)) # say('今天是个好日子') # class logging(object): # def __init__(self, user_type=None): # self.user_type = user_type # # def __call__(self, func): # 接受函数 # def wrapper(*args, **kwargs): # if self.user_type==1: # print('我是普通用户') # elif self.user_type==2: # print('我是管理员') # else: # print('我是普通用户') # func(*args, **kwargs) # # return wrapper # 返回函数 # # # @logging(user_type=1) # def say(something): # user_type = 1 # print("say {}!".format(something)) # # say('今天天气不错') import time #一个装饰器相当于闭包 def set_func(func): def inner(*args,**kwargs): start_time = time.time() #func(args,kwargs)#不行,相当于传递两个参数,一个元组,一个字典 # func(*args,**kwargs)#拆包 end_time = time.time() print('装饰器二号进行装饰alltime%f' % (end_time - start_time)) return '<td>' + str(func(*args,**kwargs)) + '<td>' return inner #一个装饰器相当于闭包 def set_func_1(func): def inner(*args,**kwargs): start_time = time.time() # #func(args,kwargs)#不行,相当于传递两个参数,一个元组,一个字典 # # func(*args,**kwargs)#拆包 end_time = time.time() print('装饰器一号进行装饰alltime%f' % (end_time - start_time)) return '<h1>'+str(func(*args,**kwargs)) +'<h1>' return inner @set_func_1 @set_func def f1(num): # print("__f1__%d" % num) return "__f1__%d" % num print(f1(100))
执行结果:
装饰器一号进行装饰alltime0.000001 装饰器二号进行装饰alltime0.000000 <h1><td>__f1__100<td><h1>
由此我们可以看出装饰器的执行先后顺序,谁在上面谁先执行。