如何避免TypedDict接收未定义任意参数 运行时有哪些替代方案
你对TypedDict的特性判断完全正确:Python标准库提供的TypedDict仅作用于静态类型检查阶段(比如给mypy、pyright这类检查器做类型提示用),运行时本质和普通字典没有任何区别,不会做任何字段校验,因此传入未定义的额外参数不会触发报错。
如果需要运行时禁止传入未定义参数,可根据场景选择以下替代方案:
方案1:使用Pydantic
BaseModel(最常用的运行时类型校验方案,适合需要复杂校验的场景)
除了禁止额外字段外,还会自动校验字段类型是否符合要求,支持自定义校验规则,是工业界最常用的方案:from pydantic import BaseModel, ConfigDict class X(BaseModel): model_config = ConfigDict(extra="forbid") # 严格禁止额外字段 id: int obj1 = X(id=4) print(obj1.model_dump()) # 输出 {'id':4} obj2 = X(id=4, thing=3) # 直接抛出ValidationError,提示存在未定义字段`thing`方案2:使用标准库
dataclasses(无第三方依赖,适合轻量场景)
标准库的dataclass默认就不允许传入类中未定义的参数,运行时实例化阶段直接报错,还可以通过asdict方法转为字典使用:from dataclasses import dataclass, asdict @dataclass class X: id: int obj1 = X(id=4) print(asdict(obj1)) # 输出 {'id':4} obj2 = X(id=4, thing=3) # 直接抛出TypeError: __init__() got an unexpected keyword argument 'thing'注意原生dataclass不会做类型校验,比如
X(id="4")是可以实例化成功的,如果需要类型校验可以自行在__post_init__方法中实现,或引入第三方库增强。方案3:使用标准库
NamedTuple(不可变数据场景适用)
如果你的数据不需要修改,也可以用NamedTuple,效果和dataclass类似,同样运行时禁止额外参数,支持转字典:from typing import NamedTuple class X(NamedTuple): id: int obj1 = X(id=4) print(obj1._asdict()) # 输出 {'id':4} obj2 = X(id=4, thing=3) # 直接抛出TypeError方案4:使用Pydantic 提供的
TypedDict(需要保留字典行为的场景适用)
如果希望数据结构保持普通字典的操作特性,又需要运行时校验,可以用pydantic扩展的TypedDict:from pydantic import TypedDict, validate_call class X(TypedDict, extra="forbid"): id: int @validate_call def create_x(data: X) -> X: return data obj1 = create_x(id=4) # 正常返回 {'id':4} obj2 = create_x(id=4, thing=3) # 抛出ValidationError
内容的提问来源于stack exchange,提问作者rasen58
相关产品推荐
相关产品推荐

