我对使用单行三元表达式而不是传统的多行if-else
块感兴趣。但是,比较is None
的表达式会产生不同的结果。
以下是比较谓词的条件表达式的两种形式的多行和一行变体的示例:
if pred is not None
if pred is None
代码
import operator as op
# First form
def is_not_none_multiline(a, b, pred=None):
if pred is not None:
predicate = pred
else:
predicate = lambda x, y: x + y
return predicate(a, b)
def is_not_none_oneline(a, b, pred=None):
predicate = pred if pred is not None else lambda x, y: x + y
return predicate(a, b)
# Second Form
def is_none_multiline(a, b, pred=None):
if pred is None:
predicate = lambda x, y: x + y
else:
predicate = pred
return predicate(a, b)
def is_none_oneline(a, b, pred=None):
predicate = lambda x, y: x + y if pred is None else pred
return predicate(a, b)
测试
以下是mutliline和one-line变体中可选参数的测试。最终的结果出人意料:
assert is_not_none_multiline(1, 2) == 3
assert is_not_none_oneline(1, 2) == 3
assert is_not_none_multiline(1, 2, pred=op.mul) == 2
assert is_not_none_oneline(1, 2, pred=op.mul) == 2
assert is_none_multiline(1, 2) == 3
assert is_none_oneline(1, 2) == 3
assert is_none_multiline(1, 2, pred=op.mul) == 2
assert is_none_oneline(1, 2, pred=op.mul) == 2
# ----> 4 assert is_none_oneline(1, 2, pred=op.mul) == 2
# AssertionError:
虽然pred is not None
可以作为一行使用:
predicate = pred if pred is not None else lambda x, y: x + y
pred is None
无法作为一行:
predicate = lambda x, y: x + y if pred is None else pred
详情
显然,pred
函数作为关键字传递给is_none_oneline()
时不会被评估。而是返回:
print(is_none_oneline(1, 2, pred=op.mul))
# <built-in function mul>
在执行第二种形式的两种变体时,在Python Tutor可视化中验证了此分析(请参阅此处的可视化is not None
multiline,is not None
one-line,is None
multiline,{ {3}})。
问题
目前还不清楚为什么等价的三元表达式返回函数而不是计算值。
pred is None
表达式吗?pred is None
?答案 0 :(得分:4)
只是一个简单的运算符优先级的情况。
你得到一个可调用的,它返回一个可调用的。我认为你想要这个,以确保条件以另一种方式分组:
def is_none_oneline(a, b, pred=None):
predicate = (lambda x, y: x + y) if pred is None else pred
return predicate(a, b)