京公网安备 11010802034615号
经营许可证编号:京B2-20210330
作者:豌豆花下猫
来源:Python猫
python 在涉及真值判断(Truth Value Testing)时,语法很简便。比如,在判断某个对象是否不为 None 时,或者判断容器对象是否不为空时,并不需要显示地写出判断条件,只需要在 if 或 while 关键字后面直接写上该对象即可。
下图以列表为例,if my_list 这个简短的写法可以表达出两层意思:
如果需要作出相反的判断,即“如果为 None 或为空”,只需要写成if not my_list 即可。
通常而言,当一个值本身是布尔类型时,写成"if xxx"(如果真),在语义上就很好理解。如果 xxx 本身不是布尔类型时,写成“if xxx”(如果某东西),则在语义上并不好理解。
在 C/C++/Java 之类的静态语言中,通常要先基于 xxx作一个比较操作,比如“if (xxx == null)”,以此得到一个布尔类型的值的结果,然后再进行真值判断。否则的话,若“if xxx”中有非布尔类型的值,则会报类型错误。
Python 这门动态语言在这种场景中表现出了一种灵活性,那么,我们的问题来了:为什么 Python 不需要先做一次比较操作,直接就能对任意对象作真值判断呢?
先来看看文档 中对真值判断的描述:
简单而言,Python 的任何对象都可以用在 if 或 while 或布尔操作(and、or、not)中,默认情况下认为它是 true,除非它有__bool__() 方法返回False 或者有__len__() 方法返回0 。
对于前面的例子,my_list 没有__bool__() 方法,但是它有__len__() 方法,所以它是否为 true,取决于这个方法的返回值。
——真值判断的字节码
接着,我们继续刨根问底:Python 为什么可以支持如此宽泛的真值判断呢?在执行if xxx这样的语句时,它到底在做些什么?
对于第一个问题,Python 有个内置的 bool() 类型,可以将任意对象转化成布尔值。那么,这是否意味着 Python 在进行真值判断时,会隐式地 调用 bool() 呢(即转化成if bool(xxx))?(答案为否,下文有分析)
对于第二个问题,可以先用dis 模块来查看下:
POP_JUMP_IF_FALSE指令对应的是 if 语句那行,它的含义是:
If TOS is false, sets the bytecode counter to target. TOS is popped.
如果栈顶元素为 false,则跳转到目标位置。
这里只有跳转动作的描述,仍看不到一个普通对象是如何变成布尔对象的。
Python 在解释器中到底是如何实现真值判断的呢?
——真值判断的源码实现
在微信群友 Jo 的帮助下,我找到了 CPython 的源码(文件:ceval.c、object.c):
可以看出,对于布尔类型的对象(即 Py_True 和 Py_False),代码会进入到快速处理的分支;而对于其它对象,则会用 PyObject_IsTrue() 计算出一个 int 类型的值。
PyObject_IsTrue() 函数在计算过程中,依次会获取 nb_bool、mp_length 和 sq_length 的值,对应的应该就是 __bool__() 和 __len__() 这两个魔术方法的返回值。
这个过程就是前文中所引用的官方文档的描述,正是我们想要找的答案!
另外,对于内置的 bool(),它的核心实现逻辑正是上面的 PyObject_IsTrue() 函数,源码如下(boolobject.c):
所以,Python 在对普通对象作真值判断时,并没有隐式地调用 bool(),相反它调用了一个独立的函数(PyObject_IsTrue()),而这个函数又被 bool() 所使用。
也就是说,bool() 与 if/while 语句对普通对象的真值判断,事实上是基本相同的处理逻辑。知道了原理,就会明白if bool(xxx) 这种写法是多此一举的了(我曾见到过)。
至此,我们已经回答了前文中提出的问题。
——验证真值判断的过程
接下来,有 3 个测试例子,可以作进一步的验证:
你可以暂停而思考下:bool(Test1) 与 bool(Test1()) 各是什么结果?然后依次判断剩下的两个类,结果又会是什么?
揭晓答案:
bool(Test1) # Truebool(Test2) # Truebool(Test3) # True bool(Test1()) # Truebool(Test2()) # Falsebool(Test3()) # True
原因如下:
——数字类型如何作真值判断?
除了这 3 个例子,还有一种情况值得验证,那就是对于数字类型,它们是怎么做真值判断的呢?
我们可以验证一下数字类型是否拥有那两个魔术方法:
hasattr(2020, "__bool__")hasattr(2020, "__len__")
不难验证出,数字拥有的是 __bool__() 魔术方法,并没有__len__() 魔术方法,而且所有类型的数字其实被分成了两类:
——文章小结
Python 中if xxx 这种简便的写法,虽然是正规的真值判断语法,并它但并不符合常规的语义。在 C/C++/Java 之类的语言中,要么 xxx 本身是布尔类型的值,要么是一种可返回布尔类型值的操作,但是在 Python 中,这个“xxx”竟然还可以是任意的 Python 对象!
本文通过对文档、字节码和 CPython 解释器的源码逐步分析,发现了 Python 的真值判断过程并不简单,可以提炼出以下的几个要点:
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
在数字化时代,数据已成为企业决策的核心驱动力,数据分析与数据挖掘作为解锁数据价值的关键手段,广泛应用于互联网、金融、医疗 ...
2026-04-17在数据处理、后端开发、报表生成与自动化脚本中,将 SQL 查询结果转换为字符串是一项高频且实用的操作。无论是拼接多行数据为逗 ...
2026-04-17面对一份上万行的销售明细表,要快速回答“哪个地区卖得最好”“哪款产品增长最快”“不同客户类型的购买力如何”——这些看似复 ...
2026-04-17数据分析师一天的工作,80% 的时间围绕表格结构数据展开。从一张销售明细表到一份完整的分析报告,表格结构数据贯穿始终。但你真 ...
2026-04-16在机器学习无监督学习领域,Kmeans聚类因其原理简洁、计算高效、可扩展性强的优势,成为数据聚类任务中的主流算法,广泛应用于用 ...
2026-04-16在机器学习建模实践中,特征工程是决定模型性能的核心环节之一。面对高维数据集,冗余特征、无关特征不仅会增加模型训练成本、延 ...
2026-04-16在数字化时代,用户是产品的核心资产,用户运营的本质的是通过科学的指标监测、分析与优化,实现“拉新、促活、留存、转化、复购 ...
2026-04-15在企业数字化转型、系统架构设计、数据治理与AI落地过程中,数据模型、本体模型、业务模型是三大核心基础模型,三者相互支撑、各 ...
2026-04-15数据分析师的一天,80%的时间花在表格数据上,但80%的坑也踩在表格数据上。 如果你分不清数值型和文本型的区别,不知道数据从哪 ...
2026-04-15在人工智能与机器学习落地过程中,模型质量直接决定了应用效果的优劣——无论是分类、回归、生成式模型,还是推荐、预测类模型, ...
2026-04-14在Python网络编程、接口测试、爬虫开发等场景中,HTTP请求的发送与响应处理是核心需求。Requests库作为Python生态中最流行的HTTP ...
2026-04-14 很多新人学完Python、SQL,拿到一张Excel表还是不知从何下手。 其实,90%的商业分析问题,都藏在表格的结构里。 ” 引言:为 ...
2026-04-14在回归分析中,因子(即自变量)的筛选是构建高效、可靠回归模型的核心步骤——实际分析场景中,往往存在多个候选因子,其中部分 ...
2026-04-13在机器学习模型开发过程中,过拟合是制约模型泛化能力的核心痛点——模型过度学习训练数据中的噪声与偶然细节,导致在训练集上表 ...
2026-04-13在数据驱动商业升级的今天,商业数据分析已成为企业精细化运营、科学决策的核心手段,而一套规范、高效的商业数据分析总体流程, ...
2026-04-13主讲人简介 张冲,海归统计学硕士,CDA 认证数据分析师,前云南白药集团资深数据分析师,自媒体 Python 讲师,全网课程播放量破 ...
2026-04-13在数据可视化与业务分析中,同比分析是衡量业务发展趋势、识别周期波动的核心手段,其核心逻辑是将当前周期数据与上年同期数据进 ...
2026-04-13在机器学习模型的落地应用中,预测精度并非衡量模型可靠性的唯一标准,不确定性分析同样不可或缺。尤其是在医疗诊断、自动驾驶、 ...
2026-04-10数据本身是沉默的,唯有通过有效的呈现方式,才能让其背后的规律、趋势与价值被看见、被理解、被运用。统计制图(数据可视化)作 ...
2026-04-10在全球化深度发展的今天,跨文化传播已成为连接不同文明、促进多元共生的核心纽带,其研究核心围绕“信息传递、文化解读、意义建 ...
2026-04-09