产业气象站|为什么能支持任意的真值判断?,Python( 二 )


另外 , 对于内置的bool() , 它的核心实现逻辑正是上面的PyObject_IsTrue()函数 , 源码如下(boolobject.c):
产业气象站|为什么能支持任意的真值判断?,Python
文章图片
所以 , Python在对普通对象作真值判断时 , 并没有隐式地调用bool() , 相反它调用了一个独立的函数(PyObject_IsTrue()) , 而这个函数又被bool()所使用 。
也就是说 , bool()与if/while语句对普通对象的真值判断 , 事实上是基本相同的处理逻辑 。 知道了原理 , 就会明白ifbool(xxx)这种写法是多此一举的了(我曾见到过) 。
至此 , 我们已经回答了前文中提出的问题 。
——验证真值判断的过程
接下来 , 有3个测试例子 , 可以作进一步的验证:
产业气象站|为什么能支持任意的真值判断?,Python
文章图片
你可以暂停而思考下:bool(Test1)与bool(Test1())各是什么结果?然后依次判断剩下的两个类 , 结果又会是什么?
揭晓答案:
bool(Test1)#Truebool(Test2)#Truebool(Test3)#Truebool(Test1())#Truebool(Test2())#Falsebool(Test3())#True
原因如下:
类对象没被实例化时 , bool()不会调用它的__bool__()或__len__()这两个魔术方法类对象被实例化后 , 若同时存在__bool__()或__len__()魔术方法 , 则bool()会先调用__bool__()方法(PS:这个方法要求返回值必须为bool类型 , 因此只要有它 , 就必然不需要再用__len__()方法来判断真假)——数字类型如何作真值判断?
除了这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中ifxxx这种简便的写法 , 虽然是正规的真值判断语法 , 并它但并不符合常规的语义 。 在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 。【来源:CDA数据分析师】
【产业气象站|为什么能支持任意的真值判断?,Python】声明:转载此文是出于传递更多信息之目的 。 若有来源标注错误或侵犯了您的合法权益 , 请作者持权属证明与本网联系 , 我们将及时更正、删除 , 谢谢 。 邮箱地址:newmedia@xxcb.cn