必须用 is none 而非 == none,因为 none 是单例,身份比较才语义正确;自定义类可能重载 eq 导致 == 返回错误结果;pep 8 强制要求,linter 和 mypy 均报错或警告。

为什么不能用 == 判断 None
用 == 比较 None 看似能工作,但存在隐患:某些自定义类重载了 __eq__ 方法,可能让 x == None 返回 True 即使 x 不是 None。PEP 8 明确要求用 is,因为 None 是单例对象,身份比较(is)才是语义正确的做法。
常见错误现象:if x == None: 被 linter(如 pylint、flake8)标为 E711 错误;在类型检查器(mypy)中也可能触发警告。
- 永远用
is None,不用== None -
is not None同理优于!= None - 注意不要写成
if not x:—— 这会把0、''、[]等 falsy 值一并过滤,和判None完全不是一回事
is None 在 if 语句中的标准写法
最常见场景就是条件分支里做空值防护。PEP 8 推荐显式写出 is None,不省略空格,且不加括号(除非用于复杂逻辑组合)。
if x is None:
do_something()
<p>if x is not None and x > 0: # 多条件时,is not None 放前面更安全
process(x)</p>
使用场景:函数参数默认值为 None 时的分支处理、API 返回值校验、可选字段解析等。
- 不要写
if (x is None):—— 括号多余,违反 PEP 8 - 避免
if x is None or x == "":这类混合判断;如果真要同时检查空字符串,应明确意图,比如改用if x is None or not x:,但需确认业务是否允许把0当空处理 - 在类型注解为
Optional[str]的变量上,is None是最直接、最无歧义的运行时检查方式
None 和其他 falsy 值的混淆风险
很多新手误以为 if not x: 就等价于 if x is None:,这是典型误区。Python 中有多个 falsy 值,None 只是其中之一。
错误示例:def handle_name(name): return name.upper() if name else "ANONYMOUS" —— 如果传入 name=0 或 name=[],也会走 "ANONYMOUS" 分支,但业务上很可能只希望 None 触发该逻辑。
-
None、False、0、0.0、""、[]、{}、set()都是 falsy,但只有None是“缺失值”语义 - 当函数文档或类型提示标明参数可为
None,就该用is None做精准判断 - 若需同时排除
None和空字符串,推荐分两步:if x is not None and x.strip() != "",比if x更可控
在类型检查和静态分析中的表现
现代 Python 开发普遍配合 mypy 或 pyright,它们依赖显式的 is None 判断来缩小联合类型的范围。例如 Union[str, None] 在 if x is not None: 分支内,会被推断为 str 类型。
如果写成 if x:,类型检查器无法确认 x 不为 None,后续访问 x.upper() 仍会报错。
- mypy 对
if x is None:识别良好,能正确做类型守卫(type narrowing) - 用
typing.Optional[T]注解 +is None是目前最稳妥的空值处理组合 - 某些旧代码用
if x == None:,mypy 会报error: Non-overlapping equality check,因为它知道==不具备类型守卫能力
实际写代码时,最容易被忽略的是:把 is None 当作类型守卫来用,而不是仅当作逻辑判断。一旦漏掉这层意识,后续的类型提示和静态检查就形同虚设。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











