最近都是跟遗留代码打交道,理解代码逻辑上遇到了不少的瓶颈,因此琢磨了几个小工具帮助一下
模块之间联调的时候,经常会出现扯皮的情况,双方都指责是对方的输出(输入)有问题。于是搞了这个用于调试用的包装器,可以显示输入的参数和输出的结果,这下不可以扯皮了吧
1 def log_wrapper(func):
2 @functools.wraps(func)
3 def log_func_name(self, *args, **kws):
4 logger.debug("调用函数[%s]", func.func_name)
5 logger.debug("参数为:%s, %s", [arg.__unicode__() for arg in args], kws)
6 result = func(self, *args, **kws)
7 logger.debug("返回的结果是:%s", result.__str__())
8 return result
9 return log_func_name
这个用于缓存计算量比较大或者需要IO的情况,用的时候只要@Memorized(10)这样就行了,不用更改原代码的逻辑,看起来比较干净清晰
用于包装类方法的包装器
1 class Memorized(object):
2 def __init__(self, ttl = 300):
3 self.ttl = ttl
4
5 def __call__(self, func):#只会调用一次
6 def wrapper(obj, *args):
7
8 cache = obj.__dict__.setdefault("cache", {})
9 now = time.time()
10 key_name = self.func.func_name + str(args)
11 try:
12 value, timestamp = cache[key_name]
13 if now - timestamp > self.ttl:
14 raise KeyError
15 except KeyError:
16 value = self.func(obj, *args)
17 cache[key_name] = (value, now)
18 return value
19 return wrapper
遗留代码中有个问题,有些类的内部变量值被作为开关值,外部很粗暴地直接修改了,这很明显破坏了类的封装原则。因此搞了这个装饰器查一下谁改的值XD
用于记录谁修改了指定值
1 import traceback
2 def trace_back(func):
3 def wrapper(*args):
4 infos = traceback.format_stack()
5 infos = ''.join(infos)
6 print infos
7 return func(*args)
8 return wrapper
9 class a(object):
10 def __init__(self, x):
11 self._x = x
12 @property
13 def x(self):
14 return self._x
15 @x.setter
16 @trace_back
17 def x(self, val):
18 self._x = val
19 def foo():
20 b = a(1)
21 b.x = 2
22 def bar():
23 foo()
24 bar()