if ifif语句中的表达式评估

时间:2013-04-27 00:54:36

标签: python

给出这样的代码:

if f(a) == 1:
    # do sth A
elif f(a) == 2:
    # do sth B
elif f(a) == 3:
    # do sth C
else:
    # do sth D

表达式f(a)只执行/评估一次吗?或者是否针对ifelif的每个案例执行/评估?此外,复合语句是否有所不同:例如

if f(a) == 1:
    # do sth A
elif f(a) == 2 and a > 0:
    # do sth B
elif f(a) == 3 and a < 0:
    # do sth C
else:
    # do sth D

在这种情况下,f(a)如何评估?每个案例一次性或单独一次?

3 个答案:

答案 0 :(得分:5)

测试出来:

In [7]: %paste
def f(a):
    print(a)

a = 4

if f(a) == 1:
    pass
elif f(a) == 2:
    pass
elif f(a) == 3:
    pass
else:
    pass

## -- End pasted text --
4
4
4

f(a)将继续进行评估,因为无法保证f(a)每次都会返回相同的结果,因此Python不会认为它会。您可以使用result = f(a)对其进行缓存,并使用result代替f(a)

如果这些if块中的任何一个恰好是True,那么它之后的块将不会被测试。

答案 1 :(得分:1)

我很确定每次调用它都会被执行。 (我使用python 2.7,不会认为它在3.x中有所改变)

您可以输入打印声明进行验证。

这就是为什么最好只调用一次并获得条件的返回值

您可以cache函数返回值吗?但是,调用函数1x可能更直接:

f_value = f(a)
if f_value == 1:
    # do sth A
elif f_value == 2:
    # do sth B
elif f_value == 3:
    # do sth C
else:
    # do sth D

答案 2 :(得分:1)

了解带有多个if语句的elif语句可以表示为ifelse块的嵌套集,这一点很重要。也就是说,elif只是else: if的“语法糖”(但它可以节省一定程度的缩进,因此它非常方便!)。以下块相当于代码的第一个ifelif

if f(a) == 1:
    pass
else:
    if f(a) == 2:
        pass

考虑到这一点,表达式的计算次数取决于其结果,因为如果先前的测试失败,您将只进入else部分。如果第一次呼叫f(a)返回1,则不会进行任何其他呼叫。但是,如果所有测试都失败了(除了最后一个测试),他们都需要进行评估。

同样,在使用andor的逻辑表达式中,Python会短路并且不会评估表达式中确定最终值所不需要的任何部分。

if f(a) == 1: # f(a) always gets evaluated here
     pass
elif f(a) == 2: # f(a) gets called a second time here if the "if" was failed
     pass
elif a<1 and f(a): # f(a) runs again only if both previous tests failed and a<1
     pass

总而言之,你不能告诉函数f(a)将运行多少次,除非你提前知道它的结果。如果f(a)不是幂等的(也就是说,如果它有副作用),你可能不希望以这种方式构造你的代码!