我想编写一个包含表达式的类,以便以后进行评估。例如,以下类可以包含涉及加法和乘法的表达式。
import operator as op
class Expr(object):
def __init__(self, func = lambda x: x):
self.expr = func
def __call__(self, x):
return self.expr(x)
def __sub__(self, other):
return Expr(lambda x: op.sub(self.expr(x), other))
def __mul__(self, other):
return Expr(lambda x: op.mul(self.expr(x), other))
def __rsub__(self, other):
# Subtraction is not commutative -> order matters
return Expr(lambda x: op.sub(other, self.expr(x)))
def __rmul__(self, other):
return Expr(lambda x: op.mul(other, self.expr(x)))
我们可以使用这个类来延迟表达式的评估,例如
>>> e1 = Expr()
>>> e2 = 5*e1 - 4
>>> e2(3)
11
请注意,评估顺序对于减法等非交换操作非常重要(请参阅下面5 - e1
的评估)。
>>> es = (2*e1, e1*3, e1 - 3, 4 - e1, 2*e2-3)
>>> [expr(5) for expr in es]
[10, 15, 2, -1, 39]
问题在于我想为几乎所有操作符实现这样的方法,并且明确地这样做会很烦人并明显违反DRY原则。
问题:如何使用operator
模块中的函数自动执行所有算术运算符和布尔运算符的过程?
可接受的解决方案将实施以下操作:-
,*
,否定(即-x
),==
和>
。我最感兴趣的是Python 3的解决方案,但便携式解决方案将是一个奖励!
答案 0 :(得分:1)
这是工作代码:
import operator as op
class Expr(object):
def __init__(self, func=lambda x: x):
self.expr = func
def __call__(self, x):
return self.expr(x)
def factory(name):
def operator(self, other):
return Expr(lambda x: getattr(op, name)(self.expr(x), other))
def roperator(self, other):
return Expr(lambda x: getattr(op, name)(other,self.expr(x)))
return operator,roperator
for n in ["add", "sub", "mul","truediv"]:
op,rop = factory(n)
setattr(Expr, "__{}__".format(n), op)
setattr(Expr, "__r{}__".format(n), rop)
e1 = Expr()
e2 = 2*e1 + 5
print(e2(3))