Python解析带自定义评估的布尔表达式

1 投票
2 回答
1046 浏览
提问于 2025-04-16 11:17

你好!

我正在做一个Django项目,想要存储一组课程的要求。不过这些要求并不简单,它们可能是一些组合,比如用和 / 或来连接。

((course1 or course2) and course3)

我找到了一种叫做布尔解析器的东西,基本上弄明白了它是怎么工作的。唯一的问题是,一旦它遇到一个操作数,就会用eval()来获取变量的值。

在我的情况下,这些值是动态的,需要根据某些参数来计算。关于如何实现这一点,任何建议都非常有帮助。

2 个回答

2

试试用Python表达式和eval()函数:

>>> course1 = True
>>> course2 = False
>>> course3 = True
>>> print eval('(course1 or course2) and course3')
True

不过,如果这些表达式是从你应用外部来的,那就会有安全问题,因为别人可能会注入并执行任意的Python代码。

在这种情况下,可以看看ast.literal_eval()。具体可以参考:http://docs.python.org/library/ast.html#ast.literal_eval

2

你可以像这样创建自己的名称解析器:

class NameResolver(object):
    def __getitem__(self, key):
        return "dynamic %r" % key

>>> eval("foo, bar", {}, NameResolver())
("dynamic 'foo'", "dynamic 'bar'")

不过,网站的管理员是负责设置这些要求的人吗?使用 eval() 会执行任何代码,所以这总是有潜在的安全风险。如果这些要求来自不可信的来源,那么使用 ast 模块构建自定义解析器会是更好的解决方案。

撰写回答