validate_input():
while not_valid:
attempt += 1
inpt = prompt_and_get_input()
if validate_check1(inpt) is False:
# common code for invalid_state
continue
if validate_check2(inpt) is False:
# common code for invalid_state
continue
# ... repeat ....
not_valid = False # Valid state
我想将重复的公共代码分解出来,并将其放在循环中的单个位置。我知道我可以把它放在一个函数/方法中,但仍然会有重复的调用。
我想做点什么:
validate_input():
while not_valid:
attempt += 1
inpt = prompt_and_get_input()
if validate_check1(inpt) is False:
continue
if validate_check2(inpt) is False:
continue
# ... repeat ....
not_valid = False # Valid state
else:
# We get here anytime a validate_check() fails via continue
# common vode for _invalid_state
我知道循环的else
子句只有在循环正常执行时才会执行(相对于break
)。我想要的是相反的功能,xxx
子句仅在循环没有自然迭代的情况下执行(即continue
语句)
我知道此功能没有内置功能,但是我想要做的更好的模式是什么?在我正在进行的项目中,这种模式出现了好几次。
答案 0 :(得分:1)
您可以在try / except块中使用异常。
class ValidationError(Exception):
pass
while not_valid:
try:
inpt = prompt_and_get_input()
if not validate_check1(inpt):
raise ValidationError()
...
except ValidationError:
# common code
更好的是,在validate_checkX函数中引发验证错误,然后你甚至不需要检查返回值 - 甚至根本不返回值。
(请注意,如果你确实返回了一个值,那么与False进行比较是非常不便的;如上所示,你应该if not <whatever>
。)
答案 1 :(得分:0)
在我看来,您的输入验证应该在一个地方进行管理,例如:
def is_valid(input, validators, reaction=None):
# type: AnyStr, Iterable[Callable[AnyStr, bool]], Callable[AnyStr] -> bool
for validator in validators:
if validator(input):
continue
if reaction:
reaction(input) # You could use partial to modify the reaction
return False
return True