除了这 3 个例子,还有一种情况值得验证,那就是对于数字类型,它们是怎么做真值判断的呢?
可以验证一下数字类型是否拥有那两个魔术方法:
hasattr(2020, "__bool__")
hasattr(2020, "__len__")
不难验证出,数字拥有的是 bool() 魔术方法,并没有len() 魔术方法,而且所有类型的数字其实被分成了两类:
● bool() 返回 False:所有表示 0 的数字,例如0, 0.0, 0j, Decimal(0), Fraction(0, 1)
● bool() 返回 True:所有其它非 0 的数字
小结:
Python 中if xxx 这种简便的写法,虽然是正规的真值判断语法,并它但并不符合常规的语义。在 C/C++/Java 之类的语言中,要么 xxx 本身是布尔类型的值,要么是一种可返回布尔类型值的操作,但是在 Python 中,这个“xxx”竟然还可以是任意的 Python 对象!
本文通过对文档、字节码和 CPython 解释器的源码逐步分析,发现了 Python 的真值判断过程并不简单,可以提炼出以下的几个要点:
if/while 是隐性的布尔操作符: 它们除了有“判断”真假的作用,还具有隐式地将普通对象计算出布尔结果的功能。实际的操作是解释器根据“POP_JUMP_IF_FALSE”指令来完成的,其核心逻辑跟内置的 bool() 是共用了一个底层方法
真值判断过程依赖两个魔术方法: 除非被判断对象有bool() 方法返回False 或者有len() 方法返回0 ,否则布尔操作的结果都是 True。
两个魔术方法总是会先计算bool()
数字类型也可做真值判断: 数字有bool() 魔术方法,但没有len() 魔术方法,除了表示 0 的数字为 False,其它数字都为 True