应使用 is None 而非 == None 或 not x 判断是否为 None,因 None 是单例,is 才能安全确认对象身份,避免自定义 __eq__ 干扰、假值误判及类型检查失效。
is 而不是 == 判断是否为 None
Python 中 None 是单例对象,语义上表示“无值”,不是逻辑假(False)的同义词。用 == 比较可能被重载,且语义错误;只有 is 才能安全确认对象身份。
if x is None: —— 正确,检查是否指向同一个 None 对象if x == None: —— 危险,若 x 是自定义类且实现了 __eq__,可能返回 True 即使它不是 None
if not x: —— 错误,会把 0、''、[]、False 等所有假值都当成 None
None 不能用布尔上下文代替?很多新手误以为 “None 是假值,所以 if x: 就够了”,但这是混淆了「空缺」和「空内容」。比如函数返回 0 或空字符串,往往是有意为之的结果,而 None 通常代表未设置、未返回、未找到。
None 表示“查无此键”(如 dict.get(key) 未命中),返回 '' 可能表示“该键存在但值为空”Optional[str] 允许 str 或 None,但不允许 '' 作为替代is None 作为 None 检查,not x 不会被当作类型守卫
即使写了 is None,也可能因逻辑顺序或作用域问题导致误判。常见疏漏包括:
if x is not None: 再用 x,但后续代码没缩进,导致 x 仍可能为 None
if x and x is not None: —— 前半部分已触发假值判断,冗余且误导typing.Optional 但没配合 is None 做运行时检查,类型提示只是静态约束np.nan 和 pd.NA 都不等于 None,也不能用 is None 检测,需用 pd.isna(x) 或 np.isnan(x)
return 时的返回值Python 函数默认返回 None,哪怕你忘了写 return,这点常被忽视。比如:
def maybe_return_value(flag):
if flag:
return "ok"
result = maybe_return_value(False) # result 是 None,不是未定义
if result is None: # 必须这样判断
print("no value returned")
这里 result 确实是 None,但如果你用 if not result:,当 maybe_return_value(True) 返回 "0" 或 0 时也会误入分支 —— 这种隐式转换带来的歧义,正是必须显式用 is None 的根本原因。