"and" 在变量赋值中的用例
Use cases for "and" in variable assignment
我今天发现您可以在变量赋值中使用 and
,类似于 or
的用法。我很少遇到以这种方式使用 or
,但从未听说过有人以这种方式使用 and
。这个功能是否过于晦涩而不推荐使用,或者是否有一些具体的用例有助于代码的清晰度或简洁性?
a = 1
b = 3
# c is equal to b unless a or b is False; then c is equal to the "False" value. False may be 0, [], False, etc.
c = a and b
print(f'a = {a}, b = {b}, c = {c}')
>>>a = 1, b = 3, c = 3
d = 1
e = 5
# f is equal to d unless d is False; then f is equal to e. Again, "False" may be 0, [], False, etc.
f = d or e
print(f'd = {d}, e = {e}, f = {f}')
>>>d = 1, e = 5, f = 1
似乎有一个奇怪的不一致之处,使用运算符评估条件并将变量设置为该条件的真实性(例如 g = h > i
或 j = k is l
等)显然很好。
不过,and
好像是个例外。不是评估赋值的条件权,而是根据上述注释中描述的规则对变量进行赋值。为什么 c = a and b
不根据 a
和 b
都具有真值来评估 True
或 False
? (以上示例的计算结果为 True
)
谢谢
使用 and
进行短路是一种用很少的代码表达您的意图的便捷方式(确实是一个理想的目标)。
考虑这个初始化,以及如果不知道 user
是非空的,你将不得不做什么。
name = user and user.name
当然,三元将是类似的单行
name = user.name if user else None
但是可读性好吗?
最后,当使用短路链接多个 getter 时 and
真正开始拯救你的理智。
coords = user and user.location and user.location.coords
使用 or
提供更好的默认值而不是 None
当您确定覆盖错误值不会有问题时。
name = user and user.name or 'Unnamed'
基本上,如前所述,这里发生的事情是短路评估。当 and
中的第一个值计算为 True
时,它 returns 第二个值将返回 False
值。考虑这些陈述
>>> 1 and 0
0
>>> 1 and 3
3
>>> 0 and 1
0
>>> False and "Text"
False
"Text" and False
False
Your question: Why doesn't c = a and b just evaluate to True or False depending on both a and b having truthy values?
根据Python手册,a and b
的定义是:
if a is false, then a, else b
因此在您的特定情况下 当 a
没有副作用时,以上转换为实际 Python 将等同于:
c = a if not a else b
但是 a
没有副作用的说法通常是不正确的。所以c = a and b
和c = a if not a else b
的区别如下:
对于 a and b
,如果 a
为真,则 b
将永远不会被计算,而 a
被计算一次。
与 c = a if not a else b
一样,如果 a
为真,则 b
将永远不会被评估,但 a
将被第二次评估,如果 a
确实有副作用,这可能是个问题。
我今天发现您可以在变量赋值中使用 and
,类似于 or
的用法。我很少遇到以这种方式使用 or
,但从未听说过有人以这种方式使用 and
。这个功能是否过于晦涩而不推荐使用,或者是否有一些具体的用例有助于代码的清晰度或简洁性?
a = 1
b = 3
# c is equal to b unless a or b is False; then c is equal to the "False" value. False may be 0, [], False, etc.
c = a and b
print(f'a = {a}, b = {b}, c = {c}')
>>>a = 1, b = 3, c = 3
d = 1
e = 5
# f is equal to d unless d is False; then f is equal to e. Again, "False" may be 0, [], False, etc.
f = d or e
print(f'd = {d}, e = {e}, f = {f}')
>>>d = 1, e = 5, f = 1
似乎有一个奇怪的不一致之处,使用运算符评估条件并将变量设置为该条件的真实性(例如 g = h > i
或 j = k is l
等)显然很好。
不过,and
好像是个例外。不是评估赋值的条件权,而是根据上述注释中描述的规则对变量进行赋值。为什么 c = a and b
不根据 a
和 b
都具有真值来评估 True
或 False
? (以上示例的计算结果为 True
)
谢谢
使用 and
进行短路是一种用很少的代码表达您的意图的便捷方式(确实是一个理想的目标)。
考虑这个初始化,以及如果不知道 user
是非空的,你将不得不做什么。
name = user and user.name
当然,三元将是类似的单行
name = user.name if user else None
但是可读性好吗?
最后,当使用短路链接多个 getter 时 and
真正开始拯救你的理智。
coords = user and user.location and user.location.coords
使用 or
提供更好的默认值而不是 None
当您确定覆盖错误值不会有问题时。
name = user and user.name or 'Unnamed'
基本上,如前所述,这里发生的事情是短路评估。当 and
中的第一个值计算为 True
时,它 returns 第二个值将返回 False
值。考虑这些陈述
>>> 1 and 0
0
>>> 1 and 3
3
>>> 0 and 1
0
>>> False and "Text"
False
"Text" and False
False
Your question: Why doesn't c = a and b just evaluate to True or False depending on both a and b having truthy values?
根据Python手册,a and b
的定义是:
if a is false, then a, else b
因此在您的特定情况下 当 a
没有副作用时,以上转换为实际 Python 将等同于:
c = a if not a else b
但是 a
没有副作用的说法通常是不正确的。所以c = a and b
和c = a if not a else b
的区别如下:
对于
a and b
,如果a
为真,则b
将永远不会被计算,而a
被计算一次。与
c = a if not a else b
一样,如果a
为真,则b
将永远不会被评估,但a
将被第二次评估,如果a
确实有副作用,这可能是个问题。