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

如何为被装饰的__getitem__和__setitem__正确添加类型提示?

解决Mypy签名不兼容问题

问题出在你的dict_operator装饰器没有保留原方法的精确类型签名,Mypy无法识别被装饰后的__getitem__和__setitem__与父类dict的签名匹配。

要修复这个问题,需要用ParamSpec和TypeVar让装饰器准确传递原方法的类型信息:

from typing import TypeVar, Callable, Type, ParamSpec, Any

P = ParamSpec("P")
R = TypeVar("R")
T = TypeVar("T", bound="CustomDict")

class CustomDict(dict):
    def __init__(self) -> None:
        super().__init__()

    class dict_operator:
        def __init__(self, method: Callable[P, R]) -> None:
            self.method = method

        def __get__(self, instance: T | None, owner: Type[T]) -> Callable[P, R]:
            def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
                results = self.method(instance, *args, **kwargs)
                print("Did something after __getitem__ or __setitem__")
                return results

            return wrapper

    @dict_operator
    def __getitem__(self, key: Any) -> Any:
        return super().__getitem__(key)

    @dict_operator
    def __setitem__(self, key: Any, value: Any) -> None:
        super().__setitem__(key, value)

关键修改点:

  • 新增ParamSpec("P")捕获原方法的参数类型,TypeVar("R")捕获返回值类型,让装饰器能精确传递签名。
  • 把dict_operator的__init__参数类型从Callable[..., Any]改为Callable[P, R],明确绑定原方法的参数和返回值。
  • __get__方法返回Callable[P, R],确保包装后的函数签名和原方法完全一致。
  • 调整wrapper函数的参数为*args: P.args, **kwargs: P.kwargs,返回R,严格匹配原方法的调用方式。

这样修改后,Mypy就能识别被装饰后的方法签名和父类dict的签名兼容,不会再抛出类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:33:02