Python dict.get(default) 遇到 None

难度: 2

时长: 30 min

🎯 问题概述

在 Python 中,字典的 get() 方法有一个常见的陷阱:当键存在但值为 None 时,默认值参数不会生效

这是一个很多开发者都会遇到的坑,特别是处理来自 JSON、YAML 或其他数据源的字典时。

🔍 问题演示

示例 1:示例问题

# 创建一个字典,某个键的值为 None
data = {'name': 'Alice', 'age': None}

# 你可能期望得到 '未知',但实际上会得到 None
result = data.get('age', '未知')
print(result)  # 输出: None,而不是 '未知'

示例 2:与键不存在的对比

data = {'name': 'Alice', 'age': None}

# 键存在但值为 None
print(data.get('age', '未知'))      # 输出: None

# 键不存在
print(data.get('gender', '未知'))   # 输出: '未知'

🤔 为什么会这样?

dict.get(key, default) 方法的工作原理:

  • 如果 key 存在于字典中,返回对应的值(即使值是 None

  • 如果 key 不存在于字典中,返回 default

关键区别

  • 键不存在 → 使用默认值

  • 键存在但值为 None → 返回 None,不使用默认值

📝 实际应用场景

这种情况经常出现在:

  1. JSON/API 响应处理:API 可能返回 {"age": null}

  2. 配置文件解析:YAML 中的空值被解析为 None

  3. 数据库查询结果:某些字段可能为 NULL

# 来自 API 的响应
api_response = {
    "user": "john_doe",
    "email": None,  # 用户没有设置邮箱
    "phone": "123-456-7890"
}

# 错误的做法:期望得到 '未设置'
email = api_response.get('email', '未设置')
print(email)  # 输出: None,而不是 '未设置'

💡 解决方案

方法 1:显式检查值是否为 None

value = data.get('key')
if value is None:
    value = '默认值'

方法 2:使用条件表达式

value = data['key'] if data.get('key') is not None else '默认值'

方法 3:自定义函数(推荐)

def safe_get(dictionary, key, default=None):
    value = dictionary.get(key)
    return default if value is None else value

# 使用方式
email = safe_get(api_response, 'email', '未设置')
print(email)  # 输出: '未设置'

方法 4:使用 or 运算符(有局限性)

# 注意:这种方法会把所有假值(0, '', [], False等)都替换为默认值
value = data.get('key') or '默认值'

🚨 注意事项

  • None 和键不存在是两个不同的概念

  • 使用 or 运算符时要小心,它会替换所有假值

  • 在处理重要数据时,推荐使用方法 3 的自定义函数

✅ 最佳实践

  1. 明确区分:键不存在 vs 键存在但值为 None

  2. 使用类型注解:让代码意图更清晰

  3. 编写测试:确保边界情况正确处理

  4. 文档说明:在团队中统一处理方式

from typing import Any, Optional

def get_with_default(
    data: dict, 
    key: str, 
    default: Any, 
    replace_none: bool = True
) -> Any:
    """
    安全的字典取值函数
    
    Args:
        data: 源字典
        key: 要获取的键
        default: 默认值
        replace_none: 是否将 None 替换为默认值
    
    Returns:
        如果键存在且值不为None(或replace_none为False),返回值
        否则返回默认值
    """
    if key not in data:
        return default
    
    value = data[key]
    if replace_none and value is None:
        return default
    
    return value

🎓 总结

记住这个简单的规则:

  • 键不存在get() 返回默认值

  • 键存在但值为 Noneget() 返回 None

根据你的具体需求选择合适的处理方式,避免这个常见的陷阱!