Python None 与真值判定
None 表示缺失;布尔上下文中的真值规则与“空容器/0/空串”陷阱;业务上如何区分未提供与空值。
#concept
#growing
#dev
#python
#python
[!info] related notes
Python None 与真值判定
这个概念为什么出现
API 字段经常出现三种状态:没传、传了空、传了有效值。若一律用 if value:,会把 0、""、[] 与 None 混成一种“假”,造成业务误判。
[!abstract] 一句话理解
None是单例缺失标记,用is None判断;布尔上下文有独立真值规则,空容器与 0 为假,不等于“是 None”。
最小可运行示例
先把示例放进业务场景,再看代码:
场景:用户资料更新区分“清空昵称”与“未修改昵称”
本例约定 nickname=None 表示不改,空串表示清空;这只是函数契约,不是 PATCH 通用规则。若 HTTP 字段需要区分“未传”和显式 null,解析层必须保留键是否存在(或专用哨兵/框架字段集合),不能都转换成 None。
# profile_none_truth.py
# 业务意图:正确解释可选字段的三种状态。
# 教学点:
# - is None vs 真值测试;
# - 0 与 [] 为假但不是 None;
# - 业务分支应显式。
def apply_nickname(current: str, nickname: str | None) -> str:
if nickname is None:
return current # 未提供:保持
return nickname # 提供了(含空串):覆盖
def can_ship(qty: int | None) -> str:
if qty is None:
return "missing qty"
if qty <= 0: # 负数为真,但也不能发货;业务范围需独立检查
return "qty nonpositive blocked"
return f"ship {qty}"
def main() -> None:
print(apply_nickname("old", None))
print(apply_nickname("old", ""))
print(can_ship(None))
print(can_ship(0))
print(can_ship(2))
print("bool([]):", bool([]), "[] is None:", [] is None)
if __name__ == "__main__":
main()
建议运行:
python profile_none_truth.py
期望输出:
old
missing qty
qty nonpositive blocked
ship 2
bool([]): False [] is None: False
结合场景再看三个关注点
- is None 只区分 None 与非 None;未传、显式 null 和空串的业务映射要由 API 契约指定。
- 库存 0 是合法值,不能当缺失。
- 空列表为假但仍是列表对象。
核心概念与准确模型
假值(常见)
常见假值包括 None、False、数值零、空字符串/字节串及空容器。对象优先调用 __bool__(必须返回 bool),否则调用 __len__(返回非负整数,零为假);两者都未定义通常为真。真值测试也可能抛异常。
None
- 单例:
None is None - 类型
NoneType - 常作默认参数哨兵;若 None 本身是有效输入,要用另一个专用哨兵区分未提供。
边界情况与反直觉行为
- 自定义类可通过
__bool__定义真值。 or链返回操作数:"" or "default"。- NumPy 数组真值可能抛歧义错误——库边界小心。
常见误区
[!warning] 常见误区:
if not xs等同“xs 是 None” 错误理解:假值就是缺失。
正确模型:缺失用is None;空集合是另一种业务状态。
工程实践
- Optional[X] / X | None 表示允许 None,不表示参数可省略;是否可省略由默认值决定,也不会自动执行运行时校验。
- 三态字段在文档写清。
- 配置项区分“未设置”与“设置为空字符串”。
本节总结
None 与真值是两层概念。业务分支先问“是否缺失”,再问“是否为空/为零”。
自测题
- 为什么清空昵称不能写成
if nickname:才更新? - 为什么检测 None 推荐
is?
参考答案
- 空串为假,会被当成“不更新”,无法清空。
- None 是单例;
is比身份,也避免__eq__干扰。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| Truth Value Testing | 文档 | 真值规则 |
| None | 文档 | 常量 |