链式比较并不总是执行函数调用(副作用)

问题描述 投票:0回答:1

我正在测试比较链接,我注意到在某些模式下,某些函数调用不会被执行。

如果我计划使用函数调用来执行操作,那么确保它们在执行的同时仍然简洁的最佳方法是什么? (这被认为是不好的做法吗)

def foo(bar):
    print(f"\tbar")
    return bar

a = b = False 

print (f"one = {foo(a)==foo(b)==True}")
print (f"two = {True==foo(a)==foo(b)}")
print (f"three = {foo(a)==True==foo(b)}")

a = True

print (f"one = {foo(a)==foo(b)==True}")
print (f"two = {True==foo(a)==foo(b)}")
print (f"three = {foo(a)==True==foo(b)}")

a = b = True

print (f"one = {foo(a)==foo(b)==True}")
print (f"two = {True==foo(a)==foo(b)}")
print (f"three = {foo(a)==True==foo(b)}")

输出:

    bar
    bar
one = False
    bar   < only executes once
two = False
    bar   < only executes once
three = False
    bar
    bar
one = False
    bar
    bar
two = False
    bar
    bar
three = False
    bar
    bar
one = True
    bar
    bar
two = True
    bar
    bar
three = True

注意:回顾我看到的建议问题how-do-chained-comparisons-in-python-actually-work

... 总而言之,Python 本质上是这样做的:

stack_1 = stack_2 = input('Value:')
if 1 < stack_1:
    result = False
else:
    result = stack_2 < 10

再次清除 stack_* 值。

堆栈保存未命名的中间结果以进行比较martijn-pieters

python comparison-operators side-effects
1个回答
0
投票

连锁比较

<expr1> <op1> <expr2> <op2> <expr3>

相当于

<expr1> <op1> <expr2> and <expr2> <op2> <expr3>

除了

<expr2>
两次比较仅评估一次。

由于

and
执行短路,因此仅当
<expr2> <op2> <expr3>
为 true 时才会评估
<expr1> <op1> <expr2>

所以它本质上相当于

temp1 = <expr1>
temp2 = <expr2>
result = temp1 <op1> temp2
if result:
    result = result and (temp2 <op2> <expr3>)

需要

temp2
变量来确保
<expr2>
只计算一次。如果第一次比较为假,则根本不需要评估
<expr3>

© www.soinside.com 2019 - 2024. All rights reserved.