把需要测试的代码放进装饰器,剔除代码冗余
def rangtest(*argchecks):
def decorator(func):
if not __debug__:
return func
else:
def on_call(*args,**kwargs):
print('oncall:',args)
for (idx, low,high) in argchecks:
if args[idx] < low or args[idx] > high:
errmsg = 'argument %s not in %s...%s'%(idx,low,high)
raise TypeError(errmsg)
return func(*args,**kwargs)
return on_call
return decorator
@rangtest((1,0,120))
def persinfo(name,age):
print('%s is %s years old'%(name,age))
@rangtest([0,1,12],[1,1,31],[2,0,2018])
def birthday(m,d,y):
print('birthday = {}/{}/{}'.format(m,d,y))
class Person:
def __init__(self,name,job,pay):
self.job = job
self.pay = pay
@rangtest([1,0.0,1.0])
def giveraise(self,percent):
self.pay = int(self.pay * (1+percent))
根据关键字测试:
def rangetest(**checks):
def onDesc(func):
code = func.__code__ #获取func的code对象
inputArgs = code.co_varnames[:code.co_argcount] #获取参数名
funcname = func.__name__ #函数名
errmsg = "{funcname} error {key} not in {low} - {high}"
def oncall(*args, **kwargs):
posargs = list(inputArgs)
posargs = posargs[:len(args)] #根据输入参数调整参数长度
for key,(low,high) in checks.items():
if key in kwargs:
if kwargs[key] < low or kwargs[key] > high:
raise TypeError(errmsg.format(funcname=funcname,key=key,low=low,high=high))
elif key in posargs:
pos = posargs.index(key)
if args[pos] < low or args[pos] > high:
raise TypeError(errmsg.format(funcname=funcname, key=key, low=low, high=high))
return func(*args,**kwargs)
return oncall
return onDesc
@rangetest(age=(1,120))
def fuck(name,high,weight,age):
pass
fuck('123',1,2,0)