python - 如何在不使用 eval() 或 exec() 的情况下创建规则引擎?

标签 python dictionary exec eval

我的数据库中有一个简单的规则/条件表,用于为我们的一个系统生成警报。我想创建一个规则引擎或领域特定语言。

存储在此表中的一个简单规则是..(此处省略关系)

if temp > 40 send email

请注意还会有更多这样的规则。脚本每天运行一次以评估这些规则并执行必要的操作。一开始,只有一个规则,所以我们的脚本只支持那个规则。然而,我们现在需要使其更具可扩展性以支持不同的条件/规则。我已经研究过规则引擎,但我希望以一些简单的 pythonic 方式实现这一点。目前,我只提出了 eval/exec,我知道这不是最推荐的方法。那么,实现这一目标的最佳方法是什么?

( 规则作为数据存储在数据库中,因此每个对象如“温度”,条件如“>/=..etc”,值如“40,50..etc”和 Action 如“电子邮件,短信等” .."存储在数据库中,我检索它以形成条件...如果 temp > 50 发送电子邮件,那是我的想法,然后对它们使用 exec 或 eval 以使其成为实时代码..但不确定这是否是正确的方法)

最佳答案

好吧,如果你想做的是发送电子邮件,那么使用 email module .

如果我是你,我会编写一个简单的 Python 脚本来处理一堆规则,可能只是将简单的 Python 语句写在一个单独的文件中,然后发送电子邮件/短信/...要执行的操作。

您可以使用诸如 cron 之类的服务使其每天(或其他)运行一次

例如,如果您的规则如下所示:

# Rule file: rules.py

def rule1():
    if db.getAllUsers().contains("admin"): 
        return ('email', 'no admin user in db')
    else:
        return None, None

def rule2():
    if temp > 100.0: 
        return ('sms', 'too hot in greenhouse')
    else:
        return (None, None)

...

rules = [rule1, rule2, ....]

那么您的处理脚本可能如下所示:

# Script file: engine.py

import rules
import email
...

def send_email(message, receiver):
    # function that sends an email...

def send_sms(message, receiver):
    # function that sends an sms...

actions = {'email':send_email, 'sms':send_sms, ...}    

if __name__ == '__main__':

    # Declare receiver here...

    for rule in rules.rules:
        # Does the rule return a do-able action?
        # To be really paranoid we might wrap this in a try/finally
        # in case the rules themselves have any side effects,
        # or they don't all return 2-tuples.
        act, message = rule()
        if act in actions:
            # perform the action
            actions[rule()](message, receiver) 

毫无疑问,还有其他方法可以做到这一点,例如创建一个 Pythonic DSL用它来编写规则。

关于python - 如何在不使用 eval() 或 exec() 的情况下创建规则引擎?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8828672/

相关文章:

python - 关系不存在 - Django 和 Postgres

python - 能够将字段保存到变量中并使用到 queryset.value() 中吗? Django

c# - 在列表集合中查找重复项

python - 使用字典替换列值

php - 在 Windows 上使用可执行文件的可怕之处

c - 为什么这个 Forking 示例不需要互斥锁?

php - 从 PHP 运行 Python 脚本

python - 在 python 中对数组进行快速数学运算

java - 与 Java 和 Python 相关的 XML 问题

python - 如何使用键合并 `defaultdict` 中的列表,但在该键内将列表分开?