我使用装饰器来验证到达我的函数的参数(通过字典对象),当我有 2 个或更多键时,它可以正常工作。但如果我只有 key ,它会返回错误(check_person)。我定义了 2 个函数来说明我的问题:
def required(**mandatory):
"""
:param mandatory:
:return:
"""
def decorator(f):
@wraps(f)
def wrapper(**dicts):
for argname, d in dicts.items():
for key in mandatory.get(argname, []):
if key not in d:
raise Exception('Key "%s" is missing from argument "%s"' % (key, argname))
return f(**dicts)
return wrapper
return decorator
@required(json_request=(_PROVIDER, _REPORT))
def check_campaign(json_request):
"""
:param json_request:
:return:
"""
return True
@required(json_request=(_NAME))
def check_person(json_request=None):
"""
:param json_request:
:return:
"""
return True
我需要将 check_person 更改为:
if _NAME in json_request:
return True
return False
让它发挥作用。
当我尝试时:
self.assertTrue(validator.check_person(json_request=json.loads("""{"name": "Elon Musk"}""")))
或者具体来说:
{"name": "Elon Musk"}
我得到:
Error
Traceback (most recent call last):
File "/Users/spicyramen/Documents/OpenSource/Development/Python/gonzo/utils/validate/validator_test.py", line 46, in test_person
self.assertTrue(validator.check_person(json_request=json.loads("""{"name": "Elon Musk"}""")))
File "/Users/spicyramen/Documents/OpenSource/Development/Python/gonzo/utils/validate/validator.py", line 26, in wrapper
raise Exception('Key "%s" is missing from argument "%s"' % (key, argname))
Exception: Key "n" is missing from argument "json_request"
当我的字典有超过 1 个键时,它可以正常工作(如 check_campaign)。
最佳答案
问题在于微妙的语法区别。
使用@required(json_request=(_PROVIDER, _REPORT))
,您的请求是一个元组:(_PROVIDER, _REPORT)。
相比之下,在失败的示例 @required(json_request=(_NAME))
中,请求仅为值 _NAME
。要使其成为元组,请添加逗号:@required(json_request=(_NAME,))
。这应该可以解决你所有的麻烦。
至于为什么会出现这个确切错误,您可以迭代该参数。当它是一个元组时,它会按照你想要的方式工作。当它是一个字符串时,迭代它可以得到每个字母。这就是 'n'
缺失的原因:它是 'name'
的第一个字母。
关于Python 装饰器验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43950932/