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

如何为Python类装饰器添加的函数进行类型提示?

让VSCode与mypy识别装饰器动态添加的类成员

要解决这个问题,核心是给静态类型检查工具提供明确的类型提示——运行时修改类型注解的方式行不通,因为mypy、Pyright(VSCode默认类型检查器)不会执行运行时代码,只会分析静态代码。下面是几种可行方案:

方案一:给装饰器添加泛型类型注解

直接在装饰器的类型签名中声明,被装饰后的类会新增指定成员:

from dataclasses import dataclass
from typing import TypeVar, Type, Dict

T = TypeVar("T")

def mydecorator(cls: Type[T]) -> Type[T]:
    # 定义新增成员的类型模板
    class _AddedMembers:
        def save(self) -> None:
            # 你的save方法实现逻辑
            pass
        
        my_fields_dict: Dict[str, type] = {}
    
    # 动态添加成员到原类
    setattr(cls, "save", _AddedMembers.save)
    setattr(cls, "my_fields_dict", _AddedMembers.my_fields_dict)
    
    # 类型检查器会自动识别返回的类包含原类和新增成员的类型
    return cls

@mydecorator
@dataclass
class A:
    a: str = ""

a = A()
a.save()  # 工具会正确识别该方法
a.my_fields_dict  # 工具会正确识别该字段

方案二:用Protocol协议规范新增成员

如果装饰器需要复用在多个类上,定义一个Protocol来描述新增的成员,让装饰器返回符合该协议的类:

from typing import Protocol, Dict
from dataclasses import dataclass
from typing import TypeVar, Type

class Saveable(Protocol):
    def save(self) -> None: ...
    my_fields_dict: Dict[str, type]

T = TypeVar("T")

def mydecorator(cls: Type[T]) -> Type[T & Saveable]:
    # 动态添加成员逻辑
    setattr(cls, "save", lambda self: None)
    setattr(cls, "my_fields_dict", {})
    return cls

@mydecorator
@dataclass
class A:
    a: str = ""

方案三:局部类型断言(快速临时方案)

如果不想修改装饰器,可在使用类实例时添加断言,让类型检查器信任成员存在:

from dataclasses import dataclass

@mydecorator
@dataclass
class A:
    a: str = ""

a = A()
assert hasattr(a, "save") and hasattr(a, "my_fields_dict")
a.save()  # 检查器会认可该调用

关键提醒

  • 不要尝试修改类的__annotations__属性,静态检查工具不会读取运行时修改的注解。
  • 装饰器的类型注解必须和实际添加的成员完全匹配,否则会出现类型误报或漏报。

内容的提问来源于stack exchange,提问作者chersun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 15:45:37