列出对副作用的理解 - 惯用正确或憎恶?

时间:2012-08-02 04:35:47

标签: python idiomatic

我有一个cheese个对象的列表。 Cheese有一个方法,可以使用db和诸如out_of_stock()之类的内容来处理大量内容。

所以:

[cheese.out_of_stock() for cheese in cheeses]

对我来说这感觉很草率。就像我正在为一堆副作用(零库存)做某事(创建一个列表)。

我是愚蠢的吗?这种方法是主观的吗?

6 个答案:

答案 0 :(得分:10)

列表推导用于创建列表。那不是你在这里做的,所以我会避免它。

答案 1 :(得分:5)

我个人会这样做

for cheese in cheeses:
    cheese.out_of_stock()

这对我来说更加明确。这是另一条线,但我怀疑另一个程序员阅读该代码会理解它,而列表理解版本可能会有点混乱。另外,我可以想象其他人可能会稍后出现(不知道out_of_stock没有返回值)并尝试稍后使用该列表。

我猜它没有错误。归根结底,它归结为谁将在以后阅读该代码(您自己或他人)以及他们是否会知道发生了什么。

编辑:另外,你正在使用一个可爱的函数式编程构造,从Haskell中获取令人讨厌的有状态事物......

答案 2 :(得分:4)

从语义上讲,如果cheese.out_of_stock返回一个布尔值,那就没关系了。但是,如果cheese.out_of_stock没有返回值,则不建议这样做,那么它会非常混乱且无法维护。

import this

了解更多信息

答案 3 :(得分:2)

列表推导通常用于过滤(或者类似于以后使用comprehsion的结果的东西)但不能用于替换在迭代数据上调用方法的循环。所以这可行,但它锁定丑陋。

答案 4 :(得分:1)

这很难看,不要这样做。

有一种非常类似的做法并不难看。它需要这样的预定义函数:

def consume(iter):
    for i in iter:
        pass

现在您可以编写如下代码:

consume(cheese.out_of_stock() for cheese in cheeses)

实际上,这只是Peters建议包含在一个用生成器表达式调用的函数中。虽然比列表理解要好得多,但它仍然不完美。直接使用for循环真是最好的(最明确的)。

答案 5 :(得分:0)

for cheese in cheeses: cheese.out_of_stock()

仍然是一个班轮,避免了创建不必要的列表的副作用。