Python 中哪些值会被判定为 False?None、False、0、空容器有什么区别?
简化版
Python 中 None、False、数值零、空字符串、空列表、空字典、空集合等在布尔上下文中都会被判定为 False。但它们语义不同:None 表示没有值,False 是布尔假,0 是数字零,空容器表示有容器但没有元素。
详细版
常见假值:
None
False
0
0.0
""
[]
()
{}
set()
range(0)
示例:
if not []:
print("empty list")
if not None:
print("none")
但不要把所有假值混为一谈:
value = 0
if not value:
print("这里无法区分 0、None、空字符串")
如果业务上要判断“没有传值”,应明确使用:
if value is None:
...
如果要判断容器为空:
if not items:
...
完整版教学
一、布尔上下文是什么
这些地方都会触发真值测试:
if value:
...
while value:
...
result = a or b
result = a and b
Python 不要求条件表达式必须是 bool,任何对象都能进行真值判断。
更准确地说,Python 会调用对象的真值规则,把对象解释成真或假。结果用于控制流程,但对象本身不一定变成了 True 或 False。这也是为什么 if items: 可以判断列表是否非空,if name: 可以判断字符串是否非空。
对象 value
|
v
真值测试 bool(value)
|
+--> True 分支
+--> False 分支
二、常见假值有哪些
Python 官方规则可以概括为:
None和False为假;- 数值类型的零为假;
- 空序列和空集合为假;
- 自定义对象可以通过
__bool__或__len__定义真假。
例子:
bool(None) # False
bool(0) # False
bool("") # False
bool([]) # False
bool([0]) # True
[0] 里面虽然是零,但列表本身非空,所以为 True。
| 值 | bool(...) | 语义 |
|---|---|---|
None | False | 没有值/缺失 |
False | False | 布尔假 |
0、0.0 | False | 数值零 |
"" | False | 空字符串 |
[]、{}、set() | False | 空容器 |
[0]、"0" | True | 非空容器/字符串 |
数字例子很适合面试:bool(0) 是 False,bool("0") 是 True,因为后者是长度为 1 的字符串,不是数字零。
三、None 和空值不要混淆
None 通常表示“没有值”或“缺失”:
user = None
空列表表示“有列表,但里面暂时没有元素”:
users = []
这两个语义不同。比如查询数据库:
None可能表示查询失败或没有执行;[]表示查询成功,但没有记录。
所以业务判断时要区分:
if users is None:
print("查询失败或未查询")
elif not users:
print("查询成功,但没有数据")
这类区分在接口设计里很关键。比如 get_users() 返回 None 可能表示请求失败或权限不足,返回 [] 表示请求成功但没有用户。如果你只写 if not users:,就会把失败和空结果混在一起,日志和错误处理都会被误导。
易错点:
if not value适合判断“广义为空”,但不适合判断“没有传值”;缺失值优先用is None。
四、and 和 or 返回的不一定是 bool
Python 的 and、or 返回操作数本身,不一定返回 True 或 False。
print("" or "default") # default
print("a" and "b") # b
常见用法:
name = input_name or "anonymous"
但要小心,如果 0 是合法值,这种写法会误判:
timeout = user_timeout or 30
当 user_timeout = 0 时,结果会变成 30。若 0 是合法配置,应写得更明确:
timeout = 30 if user_timeout is None else user_timeout
or 的规则是:从左到右返回第一个真值,如果都为假,返回最后一个假值。and 的规则是:从左到右返回第一个假值,如果都为真,返回最后一个真值。这就是为什么 "" or "default" 返回字符串 "default",而不是布尔 True。
print(0 or [] or "x") # x
print(1 and "ok") # ok
print([] and "ok") # []
五、自定义对象的真假
自定义对象默认通常为 True,但可以定义:
class Cart:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
cart = Cart([])
print(bool(cart)) # False
如果定义了 __bool__,优先使用 __bool__;否则可以根据 __len__ 判断。
__bool__ 必须返回布尔值,__len__ 应返回非负整数。容器类型通常通过长度决定真假,所以空列表、空字典、空集合为 False。自定义类如果表示“集合、购物车、查询结果”这类有数量概念的对象,用 __len__ 让 if cart: 自然表达“购物车是否有商品”是合理的。
六、业务代码怎么写更稳
不要机械地把所有判断都写成 if value:。要先问业务需要区分哪些状态:缺失、失败、零值、空结果、布尔假。比如分页参数 page_size = 0 可能非法,也可能表示“不限制”;用户昵称 "" 可能是空字符串输入;查询结果 [] 是成功但无数据。这些语义要用明确判断表达。
if value is None:
handle_missing()
elif value == 0:
handle_zero()
elif not value:
handle_empty_container_or_string()
如果只是判断容器是否为空,if not items: 是 Pythonic 的;如果要区分 None 和空容器,就分开写。面试回答的亮点是能说出“假值集合很多,但业务语义不同”。
七、常见误区与追问
- 误区:所有假值都可以当成同一种情况处理。
None、False、0、空容器语义不同,业务上常常必须区分。 - 误区:
and、or一定返回 bool。 它们返回操作数本身,所以常用于默认值,但也容易误伤合法的假值。 - 误区:
[0]是 False。 列表真值看是否为空,[0]非空,所以为 True。 - 追问:判断参数是否没传为什么用
is None? 因为None表示缺失,身份判断稳定,也不会把 0、空字符串、空列表误判成缺失。 - 追问:自定义对象怎么控制真假? 实现
__bool__,没有它时可由__len__决定,默认对象通常为 True。 - 追问:
timeout = user_timeout or 30有什么坑? 如果用户传入合法的0,会被当成假值替换成 30。
八、加强记忆
把真值测试记成“真假判断服务于控制流程,不等于业务语义相同”:None 是缺失,False 是布尔假,0 是数字零,空容器是有容器但没元素。判断缺失用 is None,判断容器为空用 not items,使用 and/or 默认值时要警惕合法假值被覆盖。