Python 我可以导致表达式的延迟计算吗?

Python 我可以导致表达式的延迟计算吗?,python,lazy-evaluation,Python,Lazy Evaluation,我试图定义一个对象master,该对象的属性/方法decise可以用表达式ex调用,但对该表达式的求值会推迟到decise中的某个逻辑要求时(甚至可能不会这样做)。因此,在这样的代码中: master.decide(ex) 如果decision中的逻辑表明,ex可能保持未评估状态。在代码中,ex代表“我的库的客户端提供的任意表达式”。它可以像1+2(在这里我并不真正关心惰性计算)一样简单,也可以像do\u http\u request()一样复杂。从数据库中删除记录()(我当然关心) 这可能吗

我试图定义一个对象
master
,该对象的属性/方法
decise
可以用表达式
ex
调用,但对该表达式的求值会推迟到
decise
中的某个逻辑要求时(甚至可能不会这样做)。因此,在这样的代码中:

master.decide(ex)
如果
decision
中的逻辑表明,
ex
可能保持未评估状态。在代码中,
ex
代表“我的库的客户端提供的任意表达式”。它可以像
1+2
(在这里我并不真正关心惰性计算)一样简单,也可以像
do\u http\u request()一样复杂。从数据库中删除记录()
(我当然关心)

这可能吗?在语法方面,我是灵活的,所以如果存在一个解决方案,它必须包含额外的运算符等围绕<代码> EX>代码>,我可以考虑它。但是我希望
ex
仍然是一个表达式

我曾考虑过(ab)使用短路运算符,如
,但似乎没有办法让它们返回布尔值以外的值

我能想到的最好办法是用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)
(是的,这个会有范围问题)


是否有一个神奇的函数、技巧或其他东西可以让我将
ex
保留为一个简单的表达式?

您可以在这里使用
yield
定义
协同程序

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

master=decide()
next(master)
master.send(ex1)
master.send(ex2)
您可以传递一个可调用的函数,仅传递一个不带参数的函数,该函数在需要计算表达式时被调用

lambda是实现这种可调用性的一种方法,但您也可以轻松地传递普通函数或实例方法或其他方法


这是非常正常的方法。

检查此链接:这一个不清楚您的任务中有什么
ex
。调用的是以前编码的函数吗?用户传递了字符串以进行计算?在第一个ase中,您不需要lambda,只需调用
master.decise(ex)
,python函数是可以作为参数传递的对象。@Daindware试图澄清表达式不是对象,因此它们不能作为参数传递。传递一个可调用函数(lambda或另一个函数)并在消费函数中调用它是一种可行的方法。假设客户端需要一个
ex
格式的
insert\u record\u into\u database()
。你能解释一下这将如何防止这样的表达式过早计算吗?@Angew在第一次
next
调用后,程序将继续等待
ex=yield()
并且只有在您执行
发送操作时才会向前移动。之后,程序将再次继续等待,直到您执行另一个
发送操作。我想这就是您想要的。您可以根据您的需要进行定制。据我所知,当客户端发送时,这将始终评估
ex
。这就是我试图阻止的。我想没有办法了。@Angew你可以从外部控制
ex
,而是发送一个
single
yield
来运行函数。你可以在这里控制一切。你介意举一个不使用
lambda
的例子吗。问题是@Agnew想要延迟表达式的计算,而不是延迟函数的调用。如何将表达式传递给任何对象并防止对其求值?无论何时调用一个函数(修饰的或不修饰的),参数都会在调用(可能修饰的)函数之前求值,这不是吗?我能看到的唯一方法是将表达式包装成类似于
lambda
的东西,它的计算会使表达式不被计算。除了
lambda
还有什么选项?@RussAbbott:是的,您必须将表达式包装到函数中。Lambda就是这样一种方式,或者使用def:语句,可能作为类方法。当你说“类似”lambda时,你的意思是什么。@RemcoGerlich:你介意提供一个
def
-方法替代方案的例子吗。我认为不能将函数定义(使用
def
而不是
lambda
)或类定义作为参数传递。谢谢