2015-03-31 66 views
1

我試圖找到一種設計模式(或maybe an algorithm),這將幫助我以更清晰的方式編寫這些規則。有什麼建議麼?更清晰的方式來表示Python中的規則(if-else)

def get_rules(user, value): 
    if 500 <= value < 5000 and not user.address: 
     return [REQUEST_ADDRESS] 

    if value >= 5000: 
     if not user.address and not user.phone: 
      return [REQUEST_ADDRESS, REQUEST_PHONE] 
     if user.address and not user.phone: 
      return [REQUEST_PHONE] 
     if not user.address and user.phone: 
      return [REQUEST_ADDRESS] 

    # Potentially ~20 more conditions here based on various attributes of user 
    return [STATES.REQUEST_NONE] 

注:我不是在尋找一個規則引擎,因爲我不想在蟒蛇加入「商業友好」 DSL我的代碼複雜化。 Python本身是編寫這些規則的簡單語言。

有趣的讀:http://martinfowler.com/bliki/RulesEngine.html(但我仍然試圖遠離「框架」爲我做這個)。

+0

我的壞,更新片段。 「量」不算什麼,它的「價值」可以是我需要做出決定的一個變量。 – zengr 2015-03-31 21:47:41

+0

爲什麼不建立一個列表並將你需要請求的值添加到該列表中?這消除了很多情況。 – 2015-03-31 21:47:46

+0

當然,我會這樣做。但這不會減少if-else檢查。 – zengr 2015-03-31 21:49:08

回答

2

你」重新檢查你的許多不同的組合「如果一個而不是其他組合檢查不是一個和B別人檢查不是一個而不是B」的策略找出你需要發送的請求的組合。

相反,只檢查你錯過了什麼:

missing = [] 
if not user.phone: 
    missing.append(REQUEST_PHONE) 
if not user.address: 
    missing.append(REQUEST_ADDRESS) 

return missing or [REQUEST_NONE] 
2

您可以在此情況下使用的字典:

resdict = {(False, False): [REQUEST_ADDRESS, REQUEST_PHONE], 
      (True, False): [REQUEST_PHONE], 
      (False, True): [REQUEST_ADDRESS]} 
return resdict[(user.address, user.phone)] 

您也可以使用列表理解:

return [req for req, haveit in zip([REQUEST_ADDRESS, REQUEST_PHONE], [user.address, user.phone]) if not haveit] 

或者一個簡單的列表追加:

res = [] 
if not user.address: 
    res.append(REQUEST_ADDRESS) 
if not user.phone: 
    res.append(REQUEST_PHONE) 
+2

我不認爲這個秤真的好。 – 2015-03-31 21:55:57

+1

是的,如果我必須檢查兩個條件,1 user.address和user.phone,另一個user.age? – zengr 2015-03-31 21:57:03

+0

'resdict'具有複雜度爲O(2^n) – 2015-03-31 21:59:04

0

如果我理解正確的問題,您對用戶屬性的列表。如果其中一個錯誤,則應將REQUEST值添加到列表中。那麼這可能幫助:

# define all your combinations here: 
mapping = {'address': REQUEST_ADDRESS, 'phone': REQUEST_PHONE, …) 

return [value for key, value in mapping.items() 
     if not getattr(user, key, None)] 
0

看起來像你的「規則」歸結到這一點:請求值中不存在作爲對象user屬性的字段。我將假設屬性到請求的映射可以是任意的;您可以將其表示爲字典映射,例如像這樣:

rulemap = { 
     "address": REQUEST_ADDRESS, 
     "phone": REQUEST_PHONE, 
     # etc. 
    } 

然後,您可以得到請求列表通過檢查問題,它在rulemap的關鍵不存在作爲對象user屬性:

return [ rulemap[fld] for fld in rulemap.keys() if fld not in user.__dict__ ] 
相關問題