Python 链接比较(重载不可重载的“and”运算符)

Python 链接比较(重载不可重载的“and”运算符),python,Python,我在征求关于如何“接近”重载和操作符的建议。提示我正在做什么的代码示例: 导入操作符 OP={operator.ge:“>=”,operator.le:“您似乎想延迟计算或静态分析类似Python的表达式。您是否考虑过使用抽象语法树?Python可以使用ast标准库模块中的工具解析表达式,而不是计算表达式。请参阅和 与其尝试重载每个运算符,不如将Python表达式表示为数据结构,您可以对其执行任何操作。您可以对树进行修改,然后执行结果,或者将树转换为您自己的表达式和变量类 例如,ast将比较链表

我在征求关于如何“接近”重载
操作符的建议。提示我正在做什么的代码示例:

导入操作符

OP={operator.ge:“>=”,operator.le:“您似乎想延迟计算或静态分析类似Python的表达式。您是否考虑过使用抽象语法树?Python可以使用
ast
标准库模块中的工具解析表达式,而不是计算表达式。请参阅和

与其尝试重载每个运算符,不如将Python表达式表示为数据结构,您可以对其执行任何操作。您可以对树进行修改,然后执行结果,或者将树转换为您自己的
表达式
变量

例如,
ast
将比较链表示为任意长的表达式和比较运算符列表(请参见
Compare
expression类型)。这就是and链接的实现方式

编辑:下面是一个示例用法:

>>> import ast
>>> x = ast.parse("2 + 2")
>>> print ast.dump(x)
Module(body=[Expr(value=BinOp(left=Num(n=2), op=Add(), right=Num(n=2)))])
>>> eval(compile(ast.Interactive(body=[x.body[0]]), "fakefile", "single"))
4

在您的例子中,您可能不会真正让Python对表达式求值,因为您只想将Python用作表达式解析器,而不是解释器。(这就是
表达式和
变量
符号树的有效功能。)您将可能的表达式树的子集解释为传递给
模型的指令。也就是说,您将处理您感兴趣的Python子集:符号(变量),比较运算符,逻辑运算符。其余的可以引发
SyntaxError
NotImplementedError
或任何您想用来通知用户他们试图在已实现的子集之外执行某项操作的内容。

对于纯语法解决方案,您只需在其中一个比较周围加上括号,要打破Python的运算符链接:
(这听起来很有希望。我稍后会检查:)。读了一些内容,但有点困惑。我如何“延迟”这些表达式的计算?据我所知,我基本上必须通过另一个表达式运行Python脚本(如
$python transform.py original.py
),在计算代码之前查看脚本源并更改AST?或将表达式作为字符串传递给将“mis”的函数“-解释它们?我忽略了什么吗?我希望我是在回答你的问题:你通过ASTs解释的表达式必须被引用,要么像在
evaluate(“我的表达式”)
中那样被引用,要么通过转换整个外部文件。这本质上类似于Lisp中的
(quote(stuff…)
。”Mis“-解释过的Python代码不能与其他Python代码自由混合。我将在我的答案中添加一个示例。谢谢,您的答案非常准确。
model.add_constr(a <= b)
model.add_constr(b <= c)
# now i could alter add_constr to support either a tuple or two arguments enabling:
model.add_constr(a <= b, b <= c)
model.add_constr((a <= b, b <= c))
# but most pleasing would be if I could do 
model.add_constr(a <= b <= c)
# that would return for example a two tuple that could be interpreted appropriately by 
# add_constr()
>>> import ast
>>> x = ast.parse("2 + 2")
>>> print ast.dump(x)
Module(body=[Expr(value=BinOp(left=Num(n=2), op=Add(), right=Num(n=2)))])
>>> eval(compile(ast.Interactive(body=[x.body[0]]), "fakefile", "single"))
4
b_expr = b**4 + 3*b**2 - 4*x - 100
model.add_constr(a <= b_expr, b_expr <= c)