celery any()语句在任务中给出错误的结果

时间:2018-05-30 16:42:04

标签: python celery

我有一个在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

当我在没有总是渴望的情况下跑步时,在芹菜调试中我看到:

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'。

任何想法为什么芹菜在说它应该是假的时候说的是真的?

1 个答案:

答案 0 :(得分:0)

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

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

如果您不首先构建列表,则使用any会更有意义。这是因为any短路,在第一个结果之后停止而没有检查其余的可迭代结果。这使它成为生成器的良好匹配,它可以懒惰地计算其值,只需要尽可能远。您可以使用生成器表达式替换列表推导,只需删除方括号即可。但在这种情况下,我建议您更改代码,以便生成器生成bool而不是值或任何值:any(x.status != "Success" for x in self.resdict['jobs'].values())