原文標題為「MongoDB支撐的java數據類型」但內容實為 Python 真值判斷。本文釐清 `None`、假值、空容器的判斷差異,給出最佳實務。
以下物件在布林語境下皆為 False:
None、False0、0.0、0j、Decimal(0)、Fraction(0,1)''、()、[]、{}、set()、range(0)False 的物件x = [] # 空列表
y = None
# 1. if not x:
if not x: print("not x -> True") # True (空列表是假值)
if not y: print("not y -> True") # True (None 是假值)
# 問題:無法區分「空列表」與「None」
# 2. if x is None:
if x is None: print("x is None") # False
if y is None: print("y is None") # True
# 精確判斷身分 (identity)
# 3. if not x is None: (等價 if not (x is None))
if not x is None: print("not x is None") # True
if not y is None: print("not y is None") # False
# 可讀性較差,易誤讀為 (not x) is None
| 需求 | 最佳寫法 | 理由 |
|---|---|---|
| 檢查是否為 None | if x is None: / if x is not None: | 身分比較、效能最好、語意最清晰、Google 風格指南推薦 |
| 檢查「有值」 (非 None、非空、非零) | if x: | Pythonic、涵蓋所有假值、但必須確認 假值情況在業務上等同「無值」 |
| 檢查「非空容器」但允許 0/False | if x is not None and len(x) > 0: | 明確語意、避免 0/False 被誤判 |
class AlwaysTrue:
def __eq__(self, other): return True # 覆寫相等比較
obj = AlwaysTrue()
print(obj == None) # True (因為 __eq__ 總回傳 True)
print(obj is None) # False (身分比較不受 __eq__ 影響)
結論:永遠用 `is None` / `is not None` 判斷 `None`,不要用 `== None`。
# 錯誤:可變預設值在定義時只建立一次
def bad_append(item, lst=[]):
lst.append(item)
return lst
# 正確:用 None 做哨兵
def good_append(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
None:永遠用 `is None` / `is not None`。None 做哨兵。