Python 怎么判断一个对象是否真的是 None(而不是假值)?

应使用 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 通常代表未设置、未返回、未找到。

  • API 返回 None 表示“查无此键”(如 dict.get(key) 未命中),返回 '' 可能表示“该键存在但值为空”
  • 类型提示中 Optional[str] 允许 strNone,但不允许 '' 作为替代
  • 静态分析工具(如 mypy)只识别 is None 作为 None 检查,not x 不会被当作类型守卫

在类型检查和 IDE 中怎么避免漏判?

即使写了 is None,也可能因逻辑顺序或作用域问题导致误判。常见疏漏包括:

  • 先做 if x is not None: 再用 x,但后续代码没缩进,导致 x 仍可能为 None
  • 多个条件混用,如 if x and x is not None: —— 前半部分已触发假值判断,冗余且误导
  • 使用 typing.Optional 但没配合 is None 做运行时检查,类型提示只是静态约束
  • 在 pandas 或 NumPy 中,np.nanpd.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 的根本原因。