所以 - 我已经用 python 构建了一些规则引擎 - 但我对 python 相当陌生......我的引擎很好用 - 但添加新规则非常丑陋,我想知道是否有一个清理它的方法。
要记住的关键是规则有副作用,规则可以与 ands、ors 等组合 - 并且只有在整个规则成功时才应用副作用 - 即规则是否成功的检查不能与发挥副作用。
所以每条规则最终看起来都是这样的:
def sample_rule():
def check( item ):
if item.doesnt_pass_some_condition(): return None
def action_to_perform():
item.set_some_value()
item.set_some_other_value()
return action_to_perform
return Rule(check)
Run Code Online (Sandbox Code Playgroud)
这看起来非常丑陋 - 但你似乎无法执行多行 lambda 或零行lambda...我想我正在寻找类似的东西:
def sample_rule():
return Rule( lambda x: x.passes_condition(),
lambda x: {x.set_some_value(), x.set_some_other_value)}
Run Code Online (Sandbox Code Playgroud)
但条件和副作用都可以是多行,并且副作用通常是空的。
那么有没有一种更简单的模式可以适用于所有情况?(当我只有一行条件和一行副作用时,我真的不想使用上面的模式,而在其他情况下则使用完全不同的模式)
只是出于兴趣,最后你会得到类似的东西
rule1 = sample_rule().andalso( other_rule_1().or(other_rule_2)).butnot( other_rule_3)
...
...
for thing_to_check in lots_of_things:
for rule in lots_of_rules:
if rule.apply_to( thing_to_check): break # take the first rule that applies
Run Code Online (Sandbox Code Playgroud)
您可以在列表中定义多个 lambda,然后根据需要使用列表中的所有 lambda,而不是定义多行 lambda(Python 不允许):
class Rule:
def __init__(self, checks=None, actions=None):
self.checks = checks if checks else []
self.actions = actions if actions else []
def apply_to(self, item):
if all([check(item) for check in self.checks]):
return self.actions
else:
return None
sample_rule = Rule(checks=[lambda x: x.passes_condition()],
actions=[lambda x: x.set_some_value(),
lambda x: x.set_some_other_value()])
# simpler rule when no actions/side effects are needed
simple_rule = Rule(checks=[lambda x: x.passes_condition()])
Run Code Online (Sandbox Code Playgroud)
在类中给出默认值checks也意味着如果给定规则没有检查/操作,则不必定义它们;进一步简化新规则的定义。actionsNone