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三目运算的两种表达方式返回结果为什么不一样?

17 回复

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=0c=""),那么 (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

第一种基本就没写过

回到顶部