如何为Python动态添加属性做mypy类型提示?求可变替代结构
问题1:实例化后为属性添加类型提示的方法
可以通过自定义Protocol结合类型转换解决SimpleNamespace的mypy报错问题:
from typing import Protocol, cast import types # 定义描述属性结构的Protocol class MyNamespace(Protocol): s: str # 将SimpleNamespace实例转换为自定义Protocol类型 x = cast(MyNamespace, types.SimpleNamespace()) x.s = "" # mypy会认可该属性的类型,不再报错
这种方式通过Protocol声明预期的属性结构,再用cast告知mypy实例符合该结构,既保留SimpleNamespace的动态性,又获得类型提示支持。
问题2:替代dict的可变结构推荐
1. 标准库dataclasses(推荐)
默认支持可变属性,原生类型提示友好,访问语法用.,比dict更简洁:
from dataclasses import dataclass @dataclass class GroupedData: s: str = "" num: int | None = None # 实例化后可自由修改属性 x = GroupedData() x.s = "example" x.num = 123
如果需要动态添加未预定义的属性,可添加__dict__类型注释:
from dataclasses import dataclass from typing import Dict, Any @dataclass class DynamicData: s: str = "" __dict__: Dict[str, Any] = None # 允许动态添加任意属性
2. 第三方库attrs(更灵活)
比dataclass功能更丰富,支持动态属性、验证器等,类型提示兼容性好:
import attrs @attrs.define class AttrsData: s: str = "" x = AttrsData() x.dynamic_attr: int = 456 # 配合attrs的mypy插件可完美识别类型
3. 自定义动态类
如果不想依赖第三方库,可手动实现支持动态属性的类:
class DynamicNS: pass # 结合类型注释使用 x = DynamicNS() x.s: str = "test" x.num: int | None = 789
若要让mypy严格识别类型,可搭配Protocol声明属性结构,用法同问题1中的示例。
内容的提问来源于stack exchange,提问作者enabtay0s9ex8dyq
相关产品推荐
相关产品推荐

