再议装饰器
# 定义函数:完成包裹数据 def makeBold(fn): def wrapped(): return "<b>" + fn() + "</b>" return wrapped # 定义函数:完成包裹数据 def makeItalic(fn): def wrapped(): return "<i>" + fn() + "</i>" return wrapped @makeBold def test1(): return "hello world-1" @makeItalic def test2(): return "hello world-2" @makeBold @makeItalic def test3(): return "hello world-3" print(test1()) print(test2()) print(test3())
运行结果:
hello world-1
hello world-2
hello world-3
4. 装饰器(decorator)功能
- 引入日志
- 函数执行时间统计
- 执行函数前预备处理
- 执行函数后清理功能
- 权限校验等场景
- 缓存
5. 装饰器示例
例1:无参数的函数
def check_time(action): def do_action(): action() return do_action @check_time def go_to_bed(): print('去睡觉') go_to_bed()
上面代码理解装饰器执行行为可理解成
result = check_time(go_to_bed) # 把go_to_bed 当做参数传入给 check_time函数,再定义一个变量用来保存check_time的运行结果 result() # check_time 函数的返回值result是一个函数, result()再调用这个函数,让它再调用go_to_bed函数
例2:被装饰的函数有参数
def check_time(action): def do_action(a,b): action(a,b) return do_action @check_time def go_to_bed(a,b): print('{}去{}睡觉'.format(a,b)) go_to_bed("zhangsan","床上")
例3:被装饰的函数有不定长参数
def test(cal): def do_cal(*args,**kwargs): cal(*args,**kwargs) return do_cal @test def demo(*args): sum = 0 for x in args: sum +=x print(sum) demo(1, 2, 3, 4)
例4:装饰器中的return
def test(cal): def do_cal(*args,**kwargs): return cal(*args,**kwargs) # 需要再这里写return语句,表示调用函数,获取函数的返回值并返回 return do_cal @test def demo(a,b): return a + b print(demo(1, 2)) #3
总结:
一般情况下为了让装饰器更通用,可以有return
例5:装饰器带参数
def outer_check(time): def check_time(action): def do_action(): if time < 22: return action() else: return '对不起,您不具有该权限' return do_action return check_time @outer_check(23) def play_game(): return '玩儿游戏' print(play_game())
提高:使用装饰器实现权限验证
以下代码不要求掌握,如果能看懂最好,如果能自己手动写出来,那就太棒了!
def outer_check(base_permission): def check_permission(action): def do_action(my_permission): if my_permission & base_permission: return action(my_permission) else: return '对不起,您不具有该权限' return do_action return check_permission READ_PERMISSION = 1 WRITE_PERMISSION = 2 EXECUTE_PERMISSION = 4 @outer_check(base_permission=READ_PERMISSION) def read(my_permission): return '读取数据' @outer_check(base_permission=WRITE_PERMISSION) def write(my_permission): return '写入数据' @outer_check(base_permission=EXECUTE_PERMISSION) def execute(my_permission): return '执行程序' print(read(5))