2012-04-23 74 views
4

我想檢查一個正則表達式模式的某個參數值,只有它們匹配時才繼續。這發生在我的應用程序中的很多地方,所以我決定讓一個函數進行檢查並在需要時調用該函數。現在,在大多數情況下,我需要檢查是在一個視圖的一開始就進行的,所以我創造了它作爲一個裝飾,像這樣:與裝飾器和正常功能的條件相同嗎?

def validate(f): 
    def _inner(request, argument=None): 
     if argument is None: 
      return HttpResponse(content="No argument given", status=400) 
     elif not re.match('^SOME_REGEX$', argument): 
      return HttpResponse(content="Invalid argument", status=400) 
     else: 
      return f(request, argument) 
    return _inner 

但也有,我需要調用檢查其他案件來自函數,作爲嵌套條件的一部分。看起來我不能直接打電話,例如validate(argument)。有什麼辦法可以使用相同的代碼作爲裝飾器以及正常的功能?或者我必須輸入兩次?

回答

3

你當然不必輸入兩次,你可以創建一個validate函數,它接受一個值並驗證它:

def validate(argument): 
    return re.match('^SOME_REGEX$', argument) 

,然後寫它調用validate功能需要裝飾:

def requires_valid(f): 
    def _inner(request, argument=None): 
     if argument is None: 
      return HttpResponse(content="No argument given", status=400) 
     elif not validate(argument): 
      return HttpResponse(content="Invalid argument", status=400) 
     else: 
      return f(request, argument) 
    return _inner 

很顯然,我不知道你的使用情況,所以你可能要爲None檢查進入validate但問題是,你不必重複相同的正則表達式的兩倍。

如果你覺得自己鑽研更深的魔法和堅持使用同樣的功能既作爲裝飾和驗證,你可以嘗試這樣的事:

def validate(f): 
    if callable(f): 
     def _inner(request, argument=None): 
      if argument is None: 
       return HttpResponse(content="No argument given", status=400) 
      elif not validate(argument): 
       return HttpResponse(content="Invalid argument", status=400) 
      else: 
       return f(request, argument) 
     return _inner 
    else: 
     return re.match('^SOME_REGEX$', f) 

但是我反對這項建議,因爲你有一個功能可以完成兩個完全不同的事情,具體取決於參數的類型。這導致代碼更難以理解。 (「你用這個函數來裝飾一個視圖,它需要一個字符串並返回bool ?!」)

+0

這很好用,謝謝!我不知道「如果可調用()」 - 這看起來像是一個非常實用的東西,我會研究。 – joschaf 2012-04-24 05:45:34