如何为注入TypedDict字段的类装饰器添加正确类型提示?
为
inject_fields装饰器添加类型提示的正确方式 要给这个实现字段注入的装饰器添加正确的类型提示,我们可以利用Python的泛型和**协议(Protocol)**来约束类型,让类型检查器(如mypy)能正确识别注解合并后的类结构。
步骤说明
- 定义一个协议(Protocol),用来描述所有包含
__annotations__属性的类(TypedDict和数据类都满足这个条件)。 - 使用泛型类型变量(TypeVar)分别表示注入字段的父类(TypedDict)和被装饰的子类(数据类)。
- 为装饰器函数和内部嵌套函数添加精确的类型注解,确保类型检查器能跟踪类的注解合并逻辑。
完整代码(含类型提示)
from dataclasses import dataclass from typing import TypedDict, Callable, TypeVar, Type, Protocol # 定义协议,约束具有__annotations__属性的类 class HasAnnotations(Protocol): __annotations__: dict[str, type] # 定义泛型类型变量,分别表示父类和子类 TParent = TypeVar('TParent', bound=HasAnnotations) TChild = TypeVar('TChild', bound=HasAnnotations) def inject_fields(parent: Type[TParent]) -> Callable[[Type[TChild]], Type[TChild]]: def doit(cls: Type[TChild]) -> Type[TChild]: # 合并父类和子类的注解 cls.__annotations__ = parent.__annotations__ | cls.__annotations__ return cls return doit # 使用示例 class UserDB(TypedDict): id: int @dataclass @inject_fields(UserDB) class UserDC: name: str # 类型检查验证 user = UserDC(id=1, name="Alice") # mypy会正确识别id和name字段 print(user.id, user.name)
类型提示的作用
- 这个实现能让类型检查器正确推断出
UserDC类包含id和name两个字段,避免出现"未定义属性"的类型错误。 - 泛型和协议的组合既保证了灵活性(支持任何带有
__annotations__的类),又保证了类型安全性。
内容的提问来源于stack exchange,提问作者wordhydrogen
相关产品推荐
相关产品推荐

