【问题标题】:celery any() statement giving wrong result inside taskcelery any() 语句在任务中给出错误的结果
【发布时间】:2018-05-30 16:42:03
【问题描述】:

我有以下代码在 celery 任务中运行,self.resdict['jobs'] 包含子任务列表,我在 while 循环中检查它们的状态。

       while any([x.status for x in self.resdict['jobs'].values() if x.status is not 'SUCCESS']):
            print([x.status for x in self.resdict['jobs'].values() if x.status is not 'SUCCESS'])
            print(any([x.status for x in self.resdict['jobs'].values() if x.status is not 'SUCCESS']))
            time.sleep(.5)
       else:
            for a in self.resdict['accounts'][0]['result']:
                account = a['number'] if isinstance(a['number'], str) else False
                self.resdict[account] = self.resdict['jobs'][account].result[0]['result'][0]['Device Information']['subattributes']

当我使用 CELERY_ALWAYS_EAGER = True 和 CELERY_EAGER_PROPAGATES_EXCEPTIONS = True 运行此代码时,如果列表包含所有“SUCCESS”,它会给我预期的结果

所以当我总是渴望跑步时,我得到了什么:

print([x.status for x in self.resdict['jobs'].values() if x.status is not 'SUCCESS']) = ['SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS']
print(any([x.status for x in self.resdict['jobs'].values() if x.status is not 'SUCCESS'])) = False

当我不总是急切地运行时,在 celery 调试中我看到:

print([x.status for x in self.resdict['jobs'].values() if x.status is not 'SUCCESS']) = ['SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS', 'SUCCESS']
print(any([x.status for x in self.resdict['jobs'].values() if x.status is not 'SUCCESS'])) = True

这是不正确的,因为列表只包含“SUCCESS”。

知道为什么 celery 在应该是 False 时说 True 吗?

【问题讨论】:

    标签: python celery


    【解决方案1】:

    您不应将字符串与is 进行比较。它有时可能会起作用,因为某些字符串将被 Python 解释器“实习”并缓存,但这种缓存不能保证在所有情况下都会发生。相反,您应该按值而不是身份进行比较,使用== 代替is!= 代替is not

    这应该可以解决您当前的问题,但我进一步建议您似乎没有以非常有用的方式使用anyany 函数在其可迭代参数中的第一个值是真值后返回 True。如果您只是想测试一个空列表,请跳过 any 并将列表本身用作布尔值。空列表是错误的,而包含任何元素(无论这些元素的值如何)的列表都是真实的。

    如果您不首先构建列表,则使用any 会更有意义。那是因为any 短路,在第一个真实结果之后停止,而不检查其余的可迭代对象。这使得它非常适合生成器,它懒惰地计算它的值,只在需要的时候计算。您可以用生成器表达式替换列表推导,只需删除方括号即可。但在这种情况下,我建议更改您的代码,以便生成器产生 bools 而不是值或什么都没有:any(x.status != "Success" for x in self.resdict['jobs'].values())

    【讨论】:

      猜你喜欢
      • 2020-08-28
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 2018-12-03
      • 2015-05-16
      • 2022-11-25
      • 1970-01-01
      • 2021-02-25
      相关资源
      最近更新 更多