1

给定这样的代码:

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)只执行/评估一次?if还是针对or的每种情况执行/评估它elif?此外,复合语句是否有任何区别:例如

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)评估?一次全部或单独为每个案例?

4

3 回答 3

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,则不会测试它之后的块。

于 2013-04-27T01:05:37.337 回答
2

重要的是要理解一个if包含多个elif语句的语句可以表示为一组嵌套的ifandelse块。也就是说,elif它只是“语法糖” else: if(但它节省了一定程度的缩进,因此非常方便!)。以下块等效于您的代码的第一个if和:elif

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

考虑到这一点,表达式被评估的次数取决于它的结果,因为else如果之前的测试失败,您只会进入部分。如果第一次调用f(a)返回1,则不会进行其他调用。但是,如果所有测试都失败了(也许最后一个除外),它们都需要进行评估。

and类似地,在使用and的逻辑表达式中or,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)不是幂等的(也就是说,如果它有副作用),您可能不希望以这种方式构造您的代码!

于 2013-04-27T01:20:08.747 回答
1

我很确定它每次被调用时都会被执行。(我使用 python 2.7,不会认为它在 3.x 中发生了变化)

你可以放一个打印语句来验证。

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

你可以缓存函数的返回值吗?但调用函数 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
于 2013-04-27T00:58:15.903 回答