2016-04-24 28 views
0
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語句)

我知道有沒有內置的功能,此功能,但是我有什麼更好的模式?這個模式在我正在進行的項目中已經出現了好幾次。

回答

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函數中的驗證錯誤,那麼你甚至不需要檢查返回值 - 甚至是返回一個值的。

(請注意,如果你返回一個值,這是非常unPythonic假比較。你應該做if not <whatever>正如我在上面)

+0

謝謝。我已經使用了Python幾個月,但它似乎仍然是非直觀的,甚至不自然的引發異常,這不是真正的錯誤。我知道這是Pythonic的方式,現在我只需要記住編碼。 – BrianHVB

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