Python三目运算的两种表达方式返回结果为什么不一样?
python 萌新(学了 3 个月左右还算吗)
一直用 condition and true or false 这个三目运算表达式(因为比 true if condition else false 少一个字符...)
今天码程序的时候发现用前一种表达式得到的结果非预期
Python 3.4.2 和 2.7.9 测试过都一样
from dogpile.cache import make_region
from dogpile.cache.api import NoValue
cache = make_region().configure(
‘dogpile.cache.dbm’, arguments={‘filename’: ‘/tmp/cache.dbm’})
session = cache.get(‘NO_EXISTS_KEY’)
print(isinstance(session, NoValue) and None or session)
print(None if isinstance(session, NoValue) else session)
Output <dogpile.cache.api.NoValue object at 0x107611c10>
Output None
Python三目运算的两种表达方式返回结果为什么不一样?
isinstance(session, NoValue) and None or session
( isinstance(session, NoValue) and None ) === None
None or session => session
这俩写法看着像,但底层逻辑确实不同。
第一种 a = b if b else c 是标准的三目运算,等价于:
if b:
a = b
else:
a = c
当 b 为真时,a 直接赋值为 b 的值。
第二种 a = b and c or d 是旧式写法,它其实是 (b and c) or d:
- 先算
b and c:如果b为真,结果就是c;如果b为假,结果就是b(False) - 再算
or d:如果前面结果为真,就取前面结果;如果为假,就取d
关键区别在于第二种写法要求 c 必须为真值。如果 b 为真但 c 为假(比如 c=0 或 c=""),那么 (b and c) 得到假值,最后会错误地返回 d。
举个例子:
b = True
c = 0
d = 5
# 写法一:返回 0(正确)
result1 = b if b else c # 返回 b 的值,但这里 b 是 True,所以...等等,这里写错了
# 修正例子:
b = True
value_if_true = 0
value_if_false = 5
# 标准三目运算
result1 = value_if_true if b else value_if_false # 返回 0
# 旧式写法
result2 = b and value_if_true or value_if_false # 返回 5(因为 0 是假值)
看到没?当 c=0 时,旧式写法会出问题。所以现在都用第一种标准写法,别用那个 and/or 的套路了。
总结:用标准的三目运算,别用旧式写法。
你都写了
condition and true or false,
你的用法里第二个是 None,并不是一个 true。
关键是理解 python 里的真值有哪些,and or 只是利用了逻辑短路特性模拟的三目运算符,可读性不好,推荐还是用 if else 的写法
以我的理解,condition and true or false 只是按照 python 语法写出的一个普通表达式。
isinstance(session, NoValue): True
True and None: None
None or session: session
所以 print 出了 session
第二个是 None。这两个写法并不是等价的。
不要用 and or 当三目运算符
因为本来就不等价
不要乱用cond and or,这是官方不推荐的用法。用A if cond else B
谁说过 and or 是三目运算符了
换一下顺序,把 None 放在最后。 (not isinstance(session, NoValue)) and session or None,
condition and ret,你这是 javascript 的习惯写法吧,python 里没怎么见过这么写的。
第一次见到这种写法的时候懵逼了半天,不得不承认 js 程序员脑洞清奇。
“谁说过 and or 是三目运算符了” +1
A and B <=> B if A else A
A or B <=> A if A else B
如果不能明确返回,就像 1 楼老实的是括号
你应该需要的是 a if True else b
我想问既然是 javascript 为什么不用 condition ? a : b
第一种基本就没写过

