当前位置: 首页 > article >正文

在 Python 里,None 可能是调用者主动传入的值,所以不能用 None 来判断参数是否被提供。

在 Python 里,None 可能是调用者主动传入的值,所以不能用 None 来判断参数是否被提供。

使用 object() 生成一个特殊的 唯一标记变量,用作默认参数的占位符,就可以明确区分调用者是否真的传递了这个参数


📌 为什么 None 不能区分调用者是否提供了参数?

来看下面的例子:

def dump_value(value, extra=None):
    if extra is None:
        print("调用方没有传递 extra 参数")
    else:
        print(f"调用方传递了 extra,值是:{extra}")

# 两种情况
dump_value(42)  # ✅ 预期:调用方没传 extra
dump_value(42, None)  # ❌ 但是这里 extra 也是 None

问题:

  • dump_value(42) 没有传 extra,函数内部 extra=None
  • dump_value(42, None) 调用者是主动传递了 None,但函数内 extra 还是 None
  • 函数内部根本无法区分这两种情况

📌 解决方案:使用 _not_set = object()

思路:

  • object() 每次调用都会返回一个新的、独一无二的对象
  • 但如果我们在全局定义 _not_set = object(),它就是唯一的,可以作为“未设置参数”的标记值。

✅ 改进版代码

# 定义一个独一无二的标记变量
_not_set = object()

def dump_value(value, extra=_not_set):
    if extra is _not_set:  # ✅ 确保 extra 是未提供的情况
        print("调用方没有传递 extra 参数")
    else:
        print(f"调用方传递了 extra,值是:{extra}")

# 测试
dump_value(42)           # 输出:调用方没有传递 extra 参数
dump_value(42, None)     # 输出:调用方传递了 extra,值是:None
dump_value(42, "hello")  # 输出:调用方传递了 extra,值是:hello

📌 代码解析

  1. _not_set = object() 定义了一个 唯一对象 作为默认值,占位。
  2. dump_value(value, extra=_not_set) 中:
    • 如果 extra 还是 _not_set,说明 调用者没传这个参数
    • 如果 extra 被赋值了(哪怕是 None,说明 调用者确实传了参数
  3. 这样,我们就能正确区分:
    • 没传 extra(参数采用默认值 _not_set)。
    • 传了 extra=None(调用者明确指定了 None)。

📌 object() 为什么适合做默认值标记?

  • 唯一性object() 每次调用都会生成 不同的对象,但 _not_set = object() 只创建一次,保证它是唯一的。
  • 不可伪造:不像 NoneFalse,调用者无法轻易传入 _not_set 这个值。
  • 内存占用小object() 只是一个简单的 Python 内部对象,占用极小的内存。

🎯 总结

  • 问题:如果默认参数用 None,无法判断调用者是否真的传递了 None,还是没传参数。
  • 解决方案:用 object() 创建一个唯一标记 _not_set 作为默认参数。
  • 好处
    • 确保只有调用者真的传入了参数,我们才会处理 extra
    • 避免误判 None,提高代码的健壮性和可读性

http://www.kler.cn/a/550131.html

相关文章:

  • .NET软件开发框架简记
  • 软件定义汽车时代的功能安全和信息安全
  • 知识文档管理系统哪个好?对比25年主流11款
  • SpringBoot(7)-Swagger
  • 【抽象代数】1.2. 半群与群
  • Kubernetes控制平面组件:Kubernetes如何使用etcd
  • 腾讯云ChatBI通过中国信通院大模型驱动的智能数据分析工具专项测试
  • Golang-GMP调度模型
  • OpenGL ES学习大纲
  • Android Studio SVN下载安装
  • rustdesk编译修改名字
  • 观察者模式说明(C语言版本)
  • 告别第三方云存储!用File Browser在Windows上自建云盘随时随地访问
  • Spring Bean 生命周期的执行流程
  • 【私人笔记】Web前端
  • 二〇二四年终总结
  • 【Git版本控制器】第三弹——版本回退,撤销修改,删除文件
  • sql server 数据库 锁教程及锁操作
  • 【开源向量数据库】Milvus简介
  • PLC数据采集解决方案