空值 None
None 是 Python 中一个特殊的常量,表示"什么都没有"。它不是 0,不是空字符串 "",不是空列表 [],也不是 False。它是一个独立的类型,只有一个值。
None 的性质
print type(None) # <type 'NoneType'>
print None == 0 # False
print None == "" # False
print None == [] # False
print None == False # False
print None is None # True
NoneType 是 Python 中最简单的类型,它只有一个实例 None。所有对 None 的引用都指向同一个对象:
a = None
b = None
print a is b # True
函数默认返回值
如果函数没有显式 return,它会自动返回 None:
def greet(name):
print "Hello,", name
# 没有 return
result = greet("Alice")
print result # None
print result is None # True
这在链式调用时需要特别注意:
s = [1, 2, 3]
result = s.sort() # sort() 原地排序,返回 None
print result # None
print s # [1, 2, 3]
很多列表方法(sort()、append()、extend()、remove())都是原地修改,返回 None。这是 Python 的设计约定:原地修改的方法不返回新对象,避免让人误以为它创建了副本。
作为默认参数
None 是设置默认参数的常用技巧,尤其是当默认参数需要是可变对象时:
# 错误示范:使用空列表作为默认值
def add_item_bad(item, items=[]):
items.append(item)
return items
print add_item_bad(1) # [1]
print add_item_bad(2) # [1, 2] —— 列表被共享了!
# 正确做法:用 None 作为哨兵值
def add_item_good(item, items=None):
if items is None:
items = []
items.append(item)
return items
print add_item_good(1) # [1]
print add_item_good(2) # [2] —— 每次创建新列表
为什么第一个函数会出错?因为默认参数在函数定义时求值,而非调用时。items=[] 在定义时创建了一个列表对象,之后每次调用都使用同一个列表。
作为哨兵值
None 常用于表示"未设置"或"未找到":
def find_user(users, name):
for user in users:
if user['name'] == name:
return user
return None # 未找到
result = find_user([{"name": "Alice"}, {"name": "Bob"}], "Charlie")
if result is None:
print "User not found"
用 is None 而不是 == None 来检查,因为 is 比较身份,速度更快,语义也更明确。
在布尔上下文中的行为
None 在 if 语句中被视为假值:
value = None
if value:
print "Has value"
else:
print "No value" # 执行这一行
Python 2 中的假值包括:None、False、0、0L、0.0、0j、""、u""、[]、()、{}、set()。其余皆为真值。
与 C/Java 的 null 对比
| 特性 | Python None | C/Java null |
|---|---|---|
| 类型 | NoneType | 无类型/任意引用类型 |
| 访问属性 | 立即报错 | 可能延迟报错 |
| 算术运算 | 报错 | 报错 |
| 布尔值 | 假 | 假 |
Python 的 None 是一个真正的对象,有类型、有身份。你不能对 None 做任何操作(除了 is 和 ==),尝试访问 None.something 会立即抛出 AttributeError。