如何创建一个生成器,以生成特定的,不相关的惰性计算表达式

问题描述

在Python中发现all()函数后发现此问题并没有像我期望的那样短路,因为您发送的列表内的表达式不是惰性计算的。所以:

all([
    previous_task is not None,self.task_type == previous_task.task_type,self.owner is None,previous_task.owner is None,self.is_sibling_of(previous_task)
    ])

例如,在此代码中,如果previous_task为None,则self.task_type == previous_task.task_type在尝试访问previous_task.task_type时仍会评估并抛出异常

尽管这样很容易解决(并且实际上短路并且很懒):

previous_task is not None and all([ 
    self.task_type == previous_task.task_type,self.is_sibling_of(previous_task)
    ])

实际上,核心问题在于列表表达式在创建时会急切地评估内部代码。

因此解决方案是创建一个生成器,因此它实际上仅逐项评估项目。但是...生成器需要对某些东西的理解才能真正生成。或带有yield参数的函数。

尽管我可以做这样的事情:

def __evaluate(self,previous_task):
    yield previous_task is not None
    yield self.task_type == previous_task.task_type
    yield self.owner is None
    yield previous_task.owner is None
    yield self.is_sibling_of(previous_task)

可读性受到损害,无法达到all的目的。

我在PEP上发现可以使用类似这样的东西:

(condition 
    for evaluation 
    in (
        previous_task is not None,self.is_sibling_of(previous_task)
    )
)

这也不起作用,因为第二个括号是集合文字,而不是生成器,它将像列表一样评估构造中集合的内容。

另一种选择是从lambda列表中进行reduce参数,如下所示:

reduce(
    lambda actual,next_function: actual and next_function(),[
        lambda: previous_task is not None
        lambda: self.task_type == previous_task.task_type
        lambda: self.owner is None
        lambda: previous_task.owner is None
        lambda: self.is_sibling_of(previous_task)
    ]
)

太冗长,尽管仍然很可读

那么...我缺少什么吗?有什么方法可以简洁地做到这一点?仅进行懒惰状态评估似乎太困难了

如果只有这些可能性,我可以考虑做一个utils库D:

编辑:忘记了我没有明确提出的显而易见的解决方案,在这里您可以只链接and,但是事实是这样做违背了all的目的。而且我认为,从长远来看,知道如何使无关值的生成器有用,而不仅仅是发送and垃圾邮件,这会妨碍可读性并迫使您以巨大的表达式“硬编码”条件

    (previous_task is not None
and self.task_type == previous_task.task_type
and self.owner is None
and previous_task.owner is None
and self.is_sibling_of(previous_task)
    )

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...