在Python循环中继续使用时执行通用代码的模式

问题描述:

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 

我想分解重复的通用代码,并将它放在循环中的单个位置。我明白我可以把它放在一个函数/方法中,但是仍然会有重复的调用。在Python循环中继续使用时执行通用代码的模式

我想这样做:

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语句)

我知道有没有内置的功能,此功能,但是我有什么更好的模式?这个模式在我正在进行的项目中已经出现了好几次。

您可以在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函数中的验证错误,那么你甚至不需要检查返回值 - 甚至是返回一个值的。

(请注意,如果你返回一个值,这是非常unPythonic假比较。你应该做if not <whatever>正如我在上面)

+0

谢谢。我已经使用了Python几个月,但它似乎仍然是非直观的,甚至不自然的引发异常,这不是真正的错误。我知道这是Pythonic的方式,现在我只需要记住编码。 – BrianHVB

在我看来你输入的验证应该从一个地方进行管理,例如:

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