在 Python 中,bool 类型其实是 int 的子类,这意味着 isinstance(True, int) 的返回值是 True。这种设计来源于 Python 早期版本还没有独立布尔类型,用整数 1 和 0 表示真假。后来引入 bool 时为了兼容旧代码,就让它继承了 int,同时把 True 和 False 实现为不可变的 int 实例。
bool 与 int 的继承关系
我们可以通过简单的代码验证 bool 是 int 的子类:
# 验证 bool 是否为 int 的子类 print(issubclass(bool, int)) # 输出 True print(isinstance(True, int)) # 输出 True print(True == 1) # 输出 True print(False == 0) # 输出 True
从上面可以看出,True 在数值比较上等于 1,False 等于 0。这是因为 bool 在 CPython 中就是两个特殊的 int 对象。
为什么不能把 bool 当 int 随意用
虽然 bool 继承自 int,但语言层面和习惯用法上并不建议把它当成普通整数来运算。主要原因有三点。
语义混淆
用 bool 做加减法虽然语法合法,但会让代码难以理解。例如下面的写法虽然能运行,但违背了布尔值的语义:
# 不推荐的写法 count = True + True + False print(count) # 输出 2
这种代码会让阅读者困惑,布尔值表达的是逻辑状态,不是数量。
类型检查限制
很多 API 会使用类型注解或显式检查来禁止 bool 作为 int 传入。因为 bool 子类化 int 只是实现细节,逻辑上它们属于不同概念。
def add(a: int):
if isinstance(a, bool):
raise TypeError('bool is not allowed')
return a + 1
try:
add(True)
except TypeError as e:
print(e) # 输出 bool is not allowed
运算符重载差异
bool 和 int 在某些上下文里行为不同,比如格式化输出和字符串转换:
print(str(True)) # 输出 'True'
print(str(1)) # 输出 '1'
print(f'{True}') # 输出 'True'
总结
Python 让 bool 成为 int 的子类主要是为了历史兼容和简化实现,但我们在写业务代码时应把布尔值和整数区分开。只在需要逻辑判断时使用 bool,不要依赖它继承自 int 的数值特性,这样可以避免隐蔽的错误并提升代码可读性。