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

抽象工厂模式中Python抽象类Exchange的方法返回类型提示是否恰当?

问题解答

直接使用联合类型是否可行?

完全可行。在抽象类Exchange中将返回类型定义为float | tuple[float, str],符合Python类型提示的规则,两个子类分别返回float或tuple[float, str]时,类型检查工具(如mypy)会认可这种实现——因为子类的返回类型是父类返回类型的协变子集,属于合法的重写。

但这种写法有个明显缺点:当调用者通过抽象类Exchange的实例调用get_account_balance时,必须同时处理两种返回类型的情况,会增加代码分支和复杂度。

更严谨的替代方案

1. 使用泛型抽象类

通过泛型可以为每个子类指定明确的返回类型,让类型提示更精准,同时避免调用者处理不确定的返回类型。示例代码如下:

from abc import ABC, abstractmethod
from typing import TypeVar, Generic

# 定义类型变量,限定为允许的两种返回类型
BalanceType = TypeVar('BalanceType', float, tuple[float, str])

class Exchange(ABC, Generic[BalanceType]):
    @abstractmethod
    def get_account_balance(self, page_source: str) -> BalanceType:
        """返回账户余额"""

# 子类1:返回float类型
class SimpleExchange(Exchange[float]):
    def get_account_balance(self, page_source: str) -> float:
        # 业务实现
        return 500.0

# 子类2:返回tuple[float, str]类型
class CurrencyExchange(Exchange[tuple[float, str]]):
    def get_account_balance(self, page_source: str) -> tuple[float, str]:
        # 业务实现
        return (1000.0, "EUR")

这种方式下,调用者在使用SimpleExchange时明确知道返回的是float,使用CurrencyExchange时明确知道返回的是带币种的元组,类型检查工具也能给出精准的提示,无需额外处理分支。

2. 拆分抽象方法(业务允许时)

如果两种返回类型对应不同的业务诉求,可以考虑在抽象类中拆分出两个独立的方法,比如:

class Exchange(ABC):
    @abstractmethod
    def get_balance_amount(self, page_source: str) -> float:
        """仅返回余额数值"""
    
    @abstractmethod
    def get_balance_with_currency(self, page_source: str) -> tuple[float, str]:
        """返回余额数值+币种"""

子类可以根据自身能力实现对应的方法(如果某个子类不需要其中一种,也可以抛出NotImplementedError),但这种方式只适用于业务逻辑支持拆分的场景。

总结

  • 若只是需要快速兼容两种返回类型,直接用float | tuple[float, str]的写法完全没问题;
  • 若追求更精准的类型提示、降低调用者的代码复杂度,泛型抽象类是更优的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 17:07:26