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

如何让mypy识别子类方法继承父类的类型注解?

让mypy识别子类方法与父类类型注解一致的方法

针对你提出的问题,有几种实用方法可以让mypy自动沿用父类方法的类型注解,无需重复编写或导入大量类型:

1. 使用@override装饰器(推荐)

从Python 3.12开始,标准库的typing模块提供了override装饰器;对于更早的版本,可以使用typing_extensions中的同名装饰器。这个装饰器明确标记方法为父类方法的重写,mypy会自动校验并沿用父类的签名和类型注解。

示例代码:

from typing_extensions import override  # Python <3.12用这个,3.12+直接from typing import override

class A:
    def test(self, value: int, *args: str, **kwargs: int) -> str:
        pass 

class B(A):
    @override
    def test(self, value, *args, **kwargs):
        # do some stuff
        return super().test(value, *args, **kwargs)

使用@override后,mypy会将子类的test方法视为与父类具有完全相同的类型签名,同时还会校验你是否正确重写了父类方法(比如方法名是否正确)。

2. 直接复制父类方法的注解

如果不想使用装饰器,可以手动将父类方法的__annotations__属性赋值给子类方法:

class A:
    def test(self, value: int, *args: str, **kwargs: int) -> str:
        pass 

class B(A):
    def test(self, value, *args, **kwargs):
        # do some stuff
        return super().test(value, *args, **kwargs)

# 复制父类方法的类型注解
B.test.__annotations__ = A.test.__annotations__

这种方式简单直接,mypy会读取子类方法的__annotations__属性来获取类型信息。

3. 针对requests.Session这类场景:使用官方提供的类型别名

对于requests.Session.get这类需要大量导入的方法,requests库已经提供了对应的类型别名(比如RequestKwargs),可以直接复用这些类型来避免重复定义:

from requests import Session, Response
from requests.models import RequestKwargs
from typing_extensions import Unpack

class CustomSession(Session):
    def get(self, url: str, *args, **kwargs: Unpack[RequestKwargs]) -> Response:
        # 处理请求头
        kwargs.setdefault('headers', {}).update({'X-Custom-Header': 'my-value'})
        return super().get(url, *args, **kwargs)

RequestKwargs包含了get方法所有关键字参数的类型定义,结合Unpack(Python 3.11+/typing_extensions)可以完整复用父类的参数类型注解。

4. 自定义装饰器复用注解

如果需要多次复用这种逻辑,可以写一个简单的装饰器来自动复制父类方法的注解:

from typing import Callable, TypeVar

T = TypeVar('T', bound=Callable)

def inherit_parent_annotations(parent_method: T) -> Callable[[T], T]:
    def decorator(child_method: T) -> T:
        child_method.__annotations__ = parent_method.__annotations__
        return child_method
    return decorator

class A:
    def test(self, value: int, *args: str, **kwargs: int) -> str:
        pass 

class B(A):
    @inherit_parent_annotations(A.test)
    def test(self, value, *args, **kwargs):
        # do some stuff
        return super().test(value, *args, **kwargs)

这个装饰器可以重复用于不同的方法,减少代码冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:25:50