我需要写很多的校验函数,这些校验函数都有 default=None, optional=False, desc=None
这几个参数。
def int_validater(min=0, max=1024,
default=None, optional=False, desc=None):
def validater(value):
if value is None:
if default is not None:
return default
elif optional:
return None
else:
raise Invalid("required")
try:
v = int(value)
except ValueError:
raise Invalid("invalid int")
if v < min:
raise Invalid("value must >= %d" % min)
elif v > max:
raise Invalid("value must <= %d" % max)
return v
return validater
def bool_validater(default=None, optional=False, desc=None):
def validater(value):
if value is None:
if default is not None:
return default
elif optional:
return None
else:
raise Invalid("required")
if isinstance(value, bool):
return value
else:
raise Invalid("invalid bool")
return validater
这些校验函数用法类似这样:
validater = int_validater(0,10,default=5)
validater(-1) # raise Invalid("value must >= %d" % min)
validater(20) # raise Invalid("value must <= %d" % max)
怎么简化代码,避免 copy? 我试了用装饰器,但是不能处理好参数顺序,装饰后的函数原型因该是下面这样:
wraped_validater(default=None, optional=False, desc=None,*args,**kwargs)
如果int_validater(0,10,default=5)
,这样 0 和 10 对应的是 optional 和 desc ,而不是*args 。
1
am241 2016-07-07 23:00:00 +08:00 via Android
看前半段想说装饰器,结果被抢答否定了
|
2
suber 2016-07-07 23:04:34 +08:00 via iPhone
你指定名字传参
|
3
chevalier 2016-07-07 23:28:59 +08:00 1
有现成的轮子: voluptuous
|
4
shyling 2016-07-07 23:54:51 +08:00 via Android 1
不要用默认值的形式
def func(*args,**kwargs)靠解析 args,kwargs 试试 |
5
guyskk OP @shyling 感谢,解决了
``` def handle_default_optional_desc(some_validater): def wrapped_validater(*args, **kwargs): default = kwargs.pop("default", None) optional = kwargs.pop("optional", False) desc = kwargs.pop("desc", None) origin_validater = some_validater(*args, **kwargs) def validater(value): if value is None: if default is not None: return default elif optional: return None else: raise Invalid("required") return origin_validater(value) return validater return wrapped_validater ``` |
7
guyskk OP |
8
guyskk OP |
9
guyskk OP |
10
ruanimal 2016-07-08 10:49:37 +08:00
你这个需要多重装饰器。。
|