我可以对表达式进行懒惰评估吗?

时间:2016-02-04 08:22:11

标签: python lazy-evaluation

我正在尝试定义一个对象master,其属性/方法decide可以使用表达式ex调用,但该表达式的评估被推迟到{{1}中的某个逻辑要求它(甚至可能不这样做)。所以,在这样的代码中:

decide
如果master.decide(ex) 中的逻辑如此说明,ex应该可以保持不被评估。在代码中,decide代表&#34;我的库的客户端提供的任意表达式。&#34;它可以像ex(我不会非常关心懒惰评估)那样简单到像1 + 2那样复杂(我当然关心)。< / p>

这样的事情可能吗?我在语法方面很灵活,所以如果存在一个必须涉及额外运算符等的解决方案 {/ em> do_http_request().delete_record_from_database(),我可以考虑一下。但我希望ex保持表达。

我在考虑(ab)使用exand之类的短路运算符,但似乎没有办法让它们返回除布尔值以外的其他值

我能想到的最好的事情是将or包裹在lambda中:

ex

或者将其作为字符串传递并使用master.decide(lambda: ex) def decide(ex): if decide_to_do_it(): result = ex() somehow_use(result)

eval

(是的,这个会有范围问题)。

是否有一个神奇的功能,技巧或其他可以让我将master.decide('ex') def decide(ex): if decide_to_do_it(): result = eval(ex) somehow_use(result) 保持为普通表达的东西?

2 个答案:

答案 0 :(得分:4)

您可以使用此处coroutine

定义yield
def decide():
  ex=yield()
  if ex:
     result = ex()
     somehow_use(result)

master=decide()
next(master)
master.send(ex1)
master.send(ex2)

答案 1 :(得分:2)

你可以传递一个可调用的,只是一个没有在需要评估表达式时调用的参数的函数。

你的lambda是制作这种可调用的一种方法,但你可以轻松地传递普通函数或实例方法等等。

这是完全正常的做法。