我正在尝试找到一种设计模式(或maybe an algorithm),它将帮助我以更清洁的方式编写这些规则。有什么建议吗?
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]
注意:我不是在寻找规则引擎,因为我不想通过在python中添加“业务友好”DSL来使我的代码复杂化。 Python本身是编写这些规则的简单语言。
有趣的阅读:http://martinfowler.com/bliki/RulesEngine.html(但我仍然试图远离“框架”为我做这件事。)
答案 0 :(得分:2)
在这种情况下你可以使用dict:
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)
答案 1 :(得分:2)
你正在检查许多不同的组合,你的“如果a而不是b,则检查不是a而b检查不是a而不是b”策略,以确定你需要发送的请求组合。
相反,只检查你缺少的东西:
missing = []
if not user.phone:
missing.append(REQUEST_PHONE)
if not user.address:
missing.append(REQUEST_ADDRESS)
return missing or [REQUEST_NONE]
答案 2 :(得分: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)]
答案 3 :(得分:0)
看起来像你的规则&#34;归结为:请求对象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__ ]