如何从 Generic 静态获取 TypeVar 参数以用于静态类型检查?

How to statically get TypeVar parameters from a Generic for use in static type checking?

我有一个class继承自typing.Generic并传入一个TypeVar作为参数。

稍后在代码中,我想:

  1. 静态地(不是在运行时)从 class
  2. 中获取 TypeVar 参数
  3. 将其别名为另一个类型变量
  4. 使用该别名键入函数的 return 提示

Python 有什么方法可以实现吗?

我唯一缺少的是第 1 步,如何从类型变量中获取类型参数


我的用例

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


TFloat = TypeVar("TFloat", bound=float)


class BaseDataClass(Generic[TFloat], ABC):

    @property
    @abstractmethod
    def data(self) -> TFloat:
        """Get data."""


class ChildDataClass(BaseDataClass[int]):

    @property
    def data(self) -> int:
        return 1

然后我将 BaseDataClassChildDataClass 导入另一个模块。

在第二个模块中,有没有办法从BaseDataClass静态获取TFloat参数,或者从ChildDataClass静态获取int参数,并在mypy?

仅供参考:我正在使用 Python 3.8.2.

没有办法 "getting" 输出类型变量。您不应该将类型变量视为可以以某种方式提取的一大块数据。相反,将其视为定义的一部分。

我认为根据你的问题,你真正想要的是一种编写接受一些 BaseDataClass[T](或这种类型的子类)和 return 的函数的方法 T 是.

如果是,请创建一个匹配您想要接受的任何定义的函数。但是不是指定内部类型必须是特定的东西,而是使用泛型来捕获它。

在这种情况下,我们选择匹配 BaseDataClass[T] 类型的任何内容,我们保留 T 泛型。我们的 return 类型将是 T 碰巧匹配的任何类型。

from typing import TypeVar
from other_module import BaseDataClass, ChildDataClass

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

def extract(wrapper: BaseDataClass[T]) -> T:
    return wrapper.data


# BaseDataClass[FloatSubclass] exactly matches against BaseDataClass[T],
# and so T will be FloatSubclass in 'extract(x)' call.

class FloatSubclass(float): pass
x: BaseDataClass[FloatSubclass]
reveal_type(extract(x))  # Mypy displays "FloatSubclass"


# ChildDataClass doesn't exactly match BaseDataClass[T], but the child
# class *is* a subtype of BaseDataClass[int], which does match.

x: ChildDataClass
reveal_type(extract(x))  # Mypy displays "int"

有关更多详细信息和示例,请参阅 mypy docs on generics