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

如何让函数返回与基类重写方法对应的实例类型?

解决方案

要实现让fn的返回值类型自动对应参数子类中get_type返回的类的实例,需要通过泛型抽象类和绑定的类型变量来实现,具体步骤如下:

1. 调整类型变量与抽象基类定义

首先定义一个绑定到任意类型的TypeVar,并让MyClass成为泛型抽象类,将类型变量关联到get_type的返回类型:

from abc import ABC, abstractmethod
from decimal import Decimal
from fractions import Fraction
from typing import Type, TypeVar, Generic

# 定义类型变量,代表get_type返回类的实例类型
InstanceT = TypeVar('InstanceT')

class MyClass(ABC, Generic[InstanceT]):
    @classmethod
    @abstractmethod
    def get_type(cls) -> Type[InstanceT]:
        ...

2. 子类继承时指定具体类型

每个子类继承MyClass时,明确指定对应的实例类型(即get_type要返回的类):

class MyDecimalSubclass(MyClass[Decimal]):
    @classmethod
    def get_type(cls) -> Type[Decimal]:
        return Decimal

class MyFractionSubclass(MyClass[Fraction]):
    @classmethod
    def get_type(cls) -> Type[Fraction]:
        return Fraction

3. 为函数fn添加泛型类型注解

让fn接收泛型参数InstanceT,并将参数类型指定为MyClass[InstanceT],返回值类型直接设为InstanceT:

def fn(arg: MyClass[InstanceT]) -> InstanceT:
    value = arg.get_type()("100")
    return value

最终完整代码

from abc import ABC, abstractmethod
from decimal import Decimal
from fractions import Fraction
from typing import Type, TypeVar, Generic

InstanceT = TypeVar('InstanceT')

class MyClass(ABC, Generic[InstanceT]):
    @classmethod
    @abstractmethod
    def get_type(cls) -> Type[InstanceT]:
        ...

class MyDecimalSubclass(MyClass[Decimal]):
    @classmethod
    def get_type(cls) -> Type[Decimal]:
        return Decimal

class MyFractionSubclass(MyClass[Fraction]):
    @classmethod
    def get_type(cls) -> Type[Fraction]:
        return Fraction

def fn(arg: MyClass[InstanceT]) -> InstanceT:
    value = arg.get_type()("100")
    return value

my_fraction = fn(MyFractionSubclass())  # 类型推断为Fraction
my_decimal = fn(MyDecimalSubclass())    # 类型推断为Decimal

print(my_fraction, my_decimal)

为什么原方案不生效?

  • 原代码中的TypeVar没有与MyClass绑定,类型检查器无法将子类的get_type返回类型与函数返回值关联起来。
  • "arg.get_type()()"这种写法不属于Python类型注解的合法语法,类型检查器无法解析这种动态表达式。

后续新增MyClass子类时,只需要在继承时指定对应的实例类型即可,类型检查器会自动推断fn的返回值类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:02:25