2

我已经搜索并找不到我的问题的直接答案,所以如果之前已经发布/回答过,我们深表歉意。我在 python 中工作,我需要传递包含变量的表达式,但我不希望它们立即被评估。

例如:

r = x*y

我希望程序记住,为了计算 r,它需要将 x 和 y 相乘,而不是当时显式计算它。我试过使用:

x = None
y = None
r = x*y

但这不允许对变量进行操作。我已经使用字符串管理它,然后使用“eval”,但它不是一个非常优雅的解决方案,而且它也非常缓慢。有没有更好的方法来做到这一点?

4

2 回答 2

4

你可以使用一个lambda表达式:

>>> x = None
>>> y = None
>>> r = lambda : x*y
>>> r()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
TypeError: unsupported operand type(s) for *: 'NoneType' and 'NoneType'
>>> x = 1
>>> y = 2
>>> r()
2

你甚至可以更喜欢一门课:

class DeferredEval(object):
    def __init__(self,func):
        self.func = func

    def __call__(self):
        return self.func()

    def __add__(self,other):
        return self.func() + other

    def __radd__(self,other):
        return other + self.func()


x = None
y = None
r = DeferredEval(lambda:x*y)

try:
    a = 1 + r
except TypeError as err:
    print "Oops, can't calculate r yet -- Reason:",err

x = 1
y = 2
print 1 + r
print r + 1

输出:

Oops, can't calculate r yet -- Reason: unsupported operand type(s) for *: 'NoneType' and 'NoneType'
3
3

当然,如果你想做一些不是加法、减法的事情,你需要在这里添加一大堆更多的方法……当然,你必须实际调用 r才能得到你的结果——但是这还不错吧?

于 2013-01-08T16:06:24.813 回答
0

您可能会查看Math Evaluator实用程序的源代码,以了解如何创建表达式以供以后进行评估。Ideone.com上的这个演示有助于展示代码可以完成的工作。

if __name__ == '__main__':
    # Run a simple demo that shows evaluator's capability.
    namespace = {}
    expression = tokens('x * y -> r')
    print expression
    evaluate('2 -> x; 3 -> y', namespace)
    expression.evaluate(namespace)
    print 'r =', namespace['r']
    alternate = Operation(Operation(Variable('x'), '+', Variable('y')), '->', Variable('r'))
    print alternate
    alternate.evaluate(namespace)
    print 'r =', namespace['r']
于 2013-01-08T18:20:20.973 回答