如何基于方法输入推断Python类的泛型参数?
Python Pipeline 泛型类型推断优化方案
当前代码的核心问题是:无类型参数的初始Pipeline()实例无法反向推导第一个泛型参数T。要让类型检查器根据第一个pipe传入的函数自动推断T,可以通过重载类方法的方式实现,以下是具体方案:
实现代码
from collections.abc import Callable from typing import Generic, TypeVar, overload, reveal_type T = TypeVar("T") U = TypeVar("U") V = TypeVar("V") class Pipeline(Generic[T, U]): def __init__(self, initial_value: U | None = None) -> None: self.value = initial_value # 类方法重载:用于第一个pipe调用,反向推导T和U @overload @classmethod def pipe(cls, cb: Callable[[T], U]) -> "Pipeline[T, U]": ... # 实例方法:用于后续链式调用,保持T不变,更新U为V def pipe(self, cb: Callable[[U], V]) -> "Pipeline[T, V]": if self.value is not None: self.value = cb(self.value) return Pipeline[T, V](self.value) # 测试示例 def int_to_str(x: int) -> str: return str(x) # 直接通过类方法调用第一个pipe,自动推断类型为Pipeline[int, str] a = Pipeline.pipe(int_to_str) reveal_type(a) # 链式调用示例 def str_to_len(x: str) -> int: return len(x) b = a.pipe(str_to_len) reveal_type(b) # 推断为Pipeline[int, int]
关键逻辑说明
- 新增类方法版本的
pipe重载:当首次调用Pipeline.pipe()时,类型检查器会从传入的Callable[[T], U]函数中,反向推导泛型参数T(函数输入类型)和U(函数输出类型),直接生成类型明确的Pipeline[T, U]实例。 - 保留实例方法的
pipe:后续链式调用时,T已被确定,仅更新输出类型U为新的V,保证类型推断的连贯性。
替代方案:显式指定初始类型
如果不想修改类结构,也可以在创建初始实例时显式声明类型参数:
a = Pipeline[int, int]() # 显式指定T=int,初始U=int a = a.pipe(int_to_str) reveal_type(a) # 推断为Pipeline[int, str]
这种方式需要手动指定初始类型,灵活性不如类方法重载方案。
内容的提问来源于stack exchange,提问作者p9f
相关产品推荐
相关产品推荐

