You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python运行时对任意键值对字典做类型提示与校验的实现方法

可行替代方案有两种,都不需要自行实现完整的dict子类:

方案1:返回只读映射视图,单独提供带校验的修改接口

这种方案无需额外依赖,从根源上禁止外部直接修改内部字典,所有修改操作必须走你暴露的带类型校验的方法:

from numbers import Number
from typing import Dict, Mapping
from types import MappingProxyType
from typeguard import typechecked

@typechecked
class Foo:
    def __init__(self, data: Dict[str, Number]):
        self._data = dict(data)
    
    @property
    def data(self) -> Mapping[str, Number]:
        # 返回只读映射代理,外部直接修改会抛出类型错误,完全禁止非法修改
        return MappingProxyType(self._data)
    
    def set_data_item(self, key: str, value: Number) -> None:
        # 所有修改必须走该方法,自动触发typeguard的类型校验
        self._data[key] = value

使用效果:

bar = Foo({'x': 2, 'y': 3})
bar.data['z'] = 'test' # 直接抛出 TypeError: 'mappingproxy' object does not support item assignment
bar.set_data_item('z', 4) # 正常运行
bar.set_data_item('z', 'test') # 触发typeguard校验错误

如果需要支持批量更新,只需额外加一个带@typechecked装饰的update_data方法即可:

def update_data(self, items: Dict[str, Number]) -> None:
    self._data.update(items)

方案2:使用第三方库封装好的运行时校验字典

如果不介意引入额外依赖,可以直接用pydantic的RootModel封装动态字典,所有字典修改操作都会自动触发运行时类型校验,无需自行实现任何接口:

from numbers import Number
from pydantic import RootModel
from typeguard import typechecked

# 定义校验规则为键是字符串、值是数值的动态字典
ValidatedDict = RootModel[dict[str, Number]]

@typechecked
class Foo:
    def __init__(self, data: dict[str, Number]):
        self._data = ValidatedDict(data)
    
    @property
    def data(self) -> ValidatedDict:
        return self._data

使用效果:

bar = Foo({'x': 2, 'y': 3})
bar.data['z'] = 5 # 正常运行
bar.data['z'] = 'test' # 直接抛出pydantic.ValidationError校验错误

这种方案的使用体验和原生字典几乎一致,所有字典操作接口都已经被底层封装好了校验逻辑,无需额外适配。


内容的提问来源于stack exchange,提问作者s-m-e

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 05:18:01