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

如何为接受ABC及子类类型的方法添加正确的类型提示?

解决方案

要解决传入抽象基类Transaction时mypy的报错问题,你可以通过调整TypeVar的定义方式,并使用typing.Type替代原生type来声明类型参数,具体实现如下:

from abc import ABC
from typing import Collection, TypeVar, Type, List

class Transaction(ABC):
    uuid: str

class CashTransaction(Transaction):
    pass

class SecurityTransaction(Transaction):
    pass

# 用bound约束TypeVar,允许所有Transaction的子类(包括自身)
TransactionType = TypeVar("TransactionType", bound=Transaction)

class RecordKeeper:
    def __init__(self):
        self._transactions: List[Transaction] = []

    def get_transactions(
        self,
        uuids: Collection[str],
        type_: Type[TransactionType],  # 使用Type[T]支持抽象类的类型对象
    ) -> List[TransactionType]:
        """Returns a list of Transactions matching uuids, ensuring they are all of type 'type_'."""
        filtered = []
        for tx in self._transactions:
            if tx.uuid in uuids and isinstance(tx, type_):
                filtered.append(tx)
        return filtered

# 所有调用场景均能通过mypy检查
uuids = ["1", "2"]
keeper = RecordKeeper()

cash_transactions = keeper.get_transactions(uuids, CashTransaction)  # 推断为List[CashTransaction]
security_transactions = keeper.get_transactions(uuids, SecurityTransaction)  # 推断为List[SecurityTransaction]
any_transactions = keeper.get_transactions(uuids, Transaction)  # 推断为List[Transaction],无mypy报错

为什么原来的实现会报错?

  1. 你之前显式枚举TypeVar的取值范围(Transaction, CashTransaction, SecurityTransaction),当传入抽象类Transaction时,type[TransactionType]等价于type[Transaction],而mypy默认认为type[T]仅接受具体类的类型对象,因此抛出Only concrete class can be given错误。
  2. 使用typing.Type[T]替代原生type[T]后,mypy会允许传递抽象类的类型对象,因为Type[T]的设计就是为了兼容抽象基类的类型引用。
  3. 改用bound=Transaction约束TypeVar,既保留了类型推断的准确性(返回值会匹配传入的类型),又避免了显式枚举类型带来的冗余和冲突。

关于重载冲突的说明

你之前尝试重载时出现的Overloaded function signatures overlap错误,是因为重载的签名存在包含关系(比如CashTransaction是Transaction的子类),mypy无法区分不同重载分支的匹配逻辑。使用带bound的TypeVar可以用单一方法实现所有类型的兼容,无需重载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:05:30