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

如何为添加额外方法的Python类装饰器添加类型注解

解决类装饰器添加方法后的类型检查问题

要让类型检查器识别装饰器动态添加的方法,核心是给装饰器添加精确的类型注解,通过类型系统描述被装饰类新增的方法签名。以下是可行的实现方案:

方案一:使用Protocol + 交集类型

通过定义协议(Protocol)描述新增方法的签名,再让装饰器返回原类与协议的交集类型,让类型检查器知晓被装饰类的新特性。

from typing import Protocol, TypeVar, Type

# 定义类型变量,代表被装饰的任意类
T = TypeVar('T')

# 定义协议,规定拥有new_method的类的结构
class WithNewMethod(Protocol):
    def new_method(self) -> None:
        ...

def add_method(cls: Type[T]) -> Type[T & WithNewMethod]:
    def new_method(self) -> None:
        print("This is the added method")
    setattr(cls, 'new_method', new_method)
    return cls

@add_method  
class Klass():
    pass

k = Klass()
k.new_method()  # 类型检查器不再报错

关键说明:

  • T & WithNewMethod是交集类型(Python 3.10+ 原生支持,低版本可使用typing_extensions.Intersection),表示返回的类同时具备原类T和协议WithNewMethod的所有特性。
  • 协议WithNewMethod仅用于类型检查,不会影响运行时逻辑。

方案二:通过类型强制转换显式声明

如果需要兼容更低版本的Python或类型检查器,可以使用cast强制转换类型,明确告知类型系统被装饰类已新增方法:

from typing import TypeVar, Type, cast

T = TypeVar('T')

# 先定义一个包含new_method的虚拟子类,仅用于类型标注
class _WithNewMethod:
    def new_method(self) -> None:
        ...

def add_method(cls: Type[T]) -> Type[T & _WithNewMethod]:
    def new_method(self) -> None:
        print("This is the added method")
    setattr(cls, 'new_method', new_method)
    # 强制转换类型,让检查器认可类的新方法
    return cast(Type[T & _WithNewMethod], cls)

@add_method  
class Klass():
    pass

k = Klass()
k.new_method()

为什么之前的尝试可能失败?

  • 使用Union类型时,Union表示“或”而非“且”,无法准确描述原类同时新增方法的情况。
  • 单独使用Protocol时,没有将原类类型与协议绑定,类型检查器无法关联被装饰类和协议的关系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 18:03:10