Python TypedDict 怎样标记部分必填字段
Python TypedDict 中只让部分字段必填,可以使用 total=False 配合 Required[T];如果大部分字段必填,则保留默认 total=True,只给可缺省字段加 NotRequired[T]。这些标记约束的是键是否必须存在,不能代替运行时输入校验,也不等同于值是否允许 None。
以下用上传元数据 UploadSpec 展示最小写法与变体,不涉及实际文件上传。示例面向 Python 3.11 及以上。官方文档:https://docs.python.org/3/library/typing.html#typing.TypedDict;Required 与 NotRequired 的设计说明见 https://peps.python.org/pep-0655/。
先写出只有标识必填的最小声明
from typing import Required, TypedDict
class UploadSpec(TypedDict, total=False):
# 即使其余字段可缺省,object_id 也必须存在且为字符串。
object_id: Required[str]
caption: str
expires_at: str | None
# 只有标识也满足契约;不需要为可缺省键补 None。
minimal: UploadSpec = {"object_id": "asset-17"}
object_id 是必填字符串;caption 可以整个键不出现,出现时应为字符串;expires_at 也可以不出现,出现时允许字符串或 None。这里的约束供静态类型工具理解,不是字典创建时自动执行的验证规则。
可以把这份声明当作三个位置的契约:object_id 属于必填键,caption 与 expires_at 属于可缺省键。total=False 提供本类声明字段的缺省规则,Required 在单个字段上明确覆盖它。

把键是否存在和取值是否为空分开
两个维度要分别回答:字典里是否必须有这个键?有键时允许什么值?在默认 total=True 的 TypedDict 中,expires_at: str | None 仍然要求 expires_at 存在,只是值可以为 None;它不能表达“键可以不传”。
| 字段声明(默认 total=True) | 键可缺省 | 值可为 None |
|---|---|---|
| value: str | 否 | 否 |
| value: str | None | 否 | 是 |
| value: NotRequired[str] | 是 | 否 |
| value: NotRequired[str | None] | 是 | 是 |
Optional[str] 的含义与 str | None 相同,并不会让键变成可缺省。对于部分更新一类接口,“不提供字段”可能代表保持原设置,“提供 None”可能代表清空设置,但这只是可选择的业务约定,TypedDict 本身不赋予这两种操作任何服务端含义。
按必填字段比例选择另一种写法
from typing import NotRequired, TypedDict
class UploadSpec(TypedDict):
# 默认 total=True,未特别标记的键是必填键。
object_id: str
caption: NotRequired[str]
expires_at: NotRequired[str | None]
这份 UploadSpec 与前面的字段契约相同,只是从“默认全可缺省,单独声明必填”换成“默认全必填,单独声明可缺省”。实际项目选一种更贴近字段比例的写法即可,不必在同一模块里重复定义同名类型。
Required 和 NotRequired 只用于 TypedDict 的字段注解;不要把它们当普通函数参数的必填声明,也不要嵌套成 Required[NotRequired[str]]。函数参数是否必须传入,应由函数签名与默认参数决定。
读取可缺省字段时保留存在性判断
下面是一段可独立保存的完整示例。describe_expiry 只描述元数据,没有请求外部服务,也不解析日期、设置过期任务或更改存储系统。
from typing import NotRequired, TypedDict
class UploadSpec(TypedDict):
# 必填标识与两项可缺省元数据分别声明。
object_id: str
caption: NotRequired[str]
expires_at: NotRequired[str | None]
def describe_expiry(spec: UploadSpec) -> str:
# 先判断键存在,避免把“未提供”与“显式清空”混为一谈。
if "expires_at" not in spec:
return "未提供过期设置"
expiry = spec["expires_at"]
if expiry is None:
return "显式清空过期设置"
return f"过期时间:{expiry}"
omitted: UploadSpec = {"object_id": "asset-17"}
cleared: UploadSpec = {"object_id": "asset-18", "expires_at": None}
scheduled: UploadSpec = {
"object_id": "asset-19",
"expires_at": "2027-01-10T08:00:00Z",
}
print(describe_expiry(omitted))
print(describe_expiry(cleared))
print(describe_expiry(scheduled))
这里用 "expires_at" in spec 区分缺键,再判断值是否为 None。若直接 spec["expires_at"],缺键时普通字典仍可能抛 KeyError;如果直接 spec.get("expires_at"),缺键与值为 None 都会得到 None,无法保留本例所需区别。

将完整片段保存为 typed_metadata.py 后,读者可在 Python 3.11 及以上运行:
# 只运行字典读取示例,不执行上传操作。 python3 typed_metadata.py
本文没有执行示例。按三个输入推导的预期文本如下;它只是运行时函数行为,不代表静态类型检查已经通过:
未提供过期设置 显式清空过期设置 过期时间:2027-01-10T08:00:00Z
明确版本与运行时边界
Python 3.11 起可以从 typing 导入 Required 与 NotRequired。维护更早版本时,需采用兼容的 typing_extensions,并按其支持范围配置;PEP 655 特别提醒老版本方案中 TypedDict 也应从 typing_extensions 导入,不要随意混用新限定符和旧 typing.TypedDict。本文不安装依赖或运行类型检查工具。
TypedDict 的值在运行时仍是普通字典。它不会替你拒绝缺少 object_id 的外部 JSON,不会检查 object_id 是不是字符串,也不会补 caption 的默认值。来自网络、文件等不可信输入,需要另设运行时解析和校验入口,再交给声明了契约的业务函数;单纯加注解或做类型断言不能把不合法数据变合法。
静态工具的诊断文字和部分读取提示会因工具及配置不同而变化,不能把一次 python3 执行成功当成类型约束已验证。反过来,类型符合声明也不意味着字符串就是有效日期或真实对象标识。
常见问题速查
NotRequired 会自动给字段设置默认值吗?
不会,它只说明键允许不出现。需要默认值时,应在读取或构造逻辑里显式定义,并决定是否要区分缺键与 None。
外层字段必填,内部字段也会跟着必填吗?
不会递归套用。嵌套值如果又是一个 TypedDict,应由内部类型单独定义其字段规则;外层 Required 只约束那个外层键。
子类写 total=False 会把继承的必填键全部变为可缺省吗?
不会,total 作用于当前类体新声明的字段,不会批量改写继承字段的既有必填性。避免通过重新声明同名字段强行改变契约。
最小选择规则是:少数必填用 total=False 加 Required,少数可缺省用默认 total 加 NotRequired;允许 None 则另写值联合类型。把这两层分清,部分必填字段的注解就不必依赖模糊的“可选”一词。
Python asyncio.Queue 关闭后怎样结束消费者
- 上一篇
- Python asyncio.Queue 关闭后怎样结束消费者
- 下一篇
- Python LiteralString 怎样约束拼接后的字符串
-
- 文章 · python教程 | 26分钟前 | Python教程 · 接口设计 · Python functools dispatch register singledispatch
- Python functools.singledispatch 怎样按参数类型选择函数
- 417浏览 收藏
-
- 文章 · python教程 | 46分钟前 |
- Python ExitStack 怎样管理动态数量的资源
- 371浏览 收藏
-
- 文章 · python教程 | 50分钟前 | 异常处理 · Python教程 · Python CalledProcessError subprocess.run check=True 非零退出码
- Python subprocess.run 怎样让非零退出码变成异常
- 394浏览 收藏
-
- 文章 · python教程 | 53分钟前 |
- Python logging Filter 怎样给记录补充字段
- 426浏览 收藏
-
- 文章 · python教程 | 59分钟前 | 标准库 · 文件读取 · 编码 · python · Python pathlib UnicodeDecodeError Path.read_text 文本编码
- Python pathlib 怎样指定文本文件编码读取
- 101浏览 收藏
-
- 文章 · python教程 | 1小时前 | Python教程 · Python 字符串拼接 类型检查 typing LiteralString SQL安全
- Python LiteralString 怎样约束拼接后的字符串
- 210浏览 收藏
-
- 文章 · python教程 | 1小时前 | 队列 · Python教程 · asyncio · Python 消费者 asyncio.Queue Queue.shutdown QueueShutDown
- Python asyncio.Queue 关闭后怎样结束消费者
- 133浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python asyncio.gather 怎样收集部分任务异常
- 449浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 523次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 580次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 607次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 557次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 377次使用
-
- Python sqlite3 Connection serialize 怎么导出数据库快照:备份窗口、内存占用与恢复校验
- 2026-08-26 501浏览
-
- Python监控网页状态:requests异常处理实战
- 2026-05-29 501浏览
-
- TensorFlow模型部署为API的TF Serving方法
- 2026-05-26 501浏览
-
- Python字符串编码转换:encode与decode详解
- 2026-05-16 501浏览
-
- TensorFlow裁剪无用算子方法详解
- 2026-05-15 501浏览

