python 装饰器的应用:控制函数是否可用
2019-11-26 本文已影响0人
远行_2a22
- 在开发中,遇到需求:
有很多的调试信息,
(1)正常流程不需要,但是本地测试却需要显示
(2)正常客户端不需要,编辑器模式下需要显示
平常的方法就是用多个标志位来控制,提交代码的时候屏蔽掉相关代码。这里使用装饰器来控制。
# -*- coding:utf-8 -*-
from enum import Enum, unique
@unique
class SwitchType(Enum):
EDITOR = 1
CLIENT = 2
SERVER = 3
def debug(*switch_type):
def fun_wrapper(func):
def wrapper(*args, **kwargs):
return SwitchTypeFunc(func, *switch_type)(*args, **kwargs)
return wrapper
return fun_wrapper
SWITCH_TYPE_MAP = {}
SWITCH_TYPE_MAP[SwitchType.CLIENT] = True
class SwitchTypeFunc(object):
def __init__(self, func, *switch_type_list):
assert func and callable(func), 'decorated func must be callable'
func_name = func.__name__
assert func_name.startswith('debug_'), 'decorated func must be named debug_xxx'
self.func = func
self.switch_type_list = list(switch_type_list)
@property
def valid(self):
for switch_type in self.switch_type_list:
if SWITCH_TYPE_MAP.get(switch_type):
return True
return False
def __call__(self, *args, **kwargs):
if self.valid and self.func:
self.func(*args, **kwargs)
else:
print('func:%s in cur switch type invalid' % self.func.__name__)
@debug(SwitchType.CLIENT,)
def debug_print_fun_info(info):
print(info)
if __name__ == '__main__':
name = 'hello_world'
debug_print_fun_info(name)
有的时候会见到使用lambda
来写装饰器,个人觉得不太好理解。不建议。
比如
def debug(*switch_type):
def fun_wrapper(func):
def wrapper(*args, **kwargs):
return SwitchTypeFunc(func, *switch_type)(*args, **kwargs)
return wrapper
return fun_wrapper
等价于
def debug(*switch_type):
def fun_wrapper(func):
return lambda *args, **kwargs: SwitchTypeFunc(func, *switch_type)(*args, **kwargs)
return fun_wrapper