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

2024-09-30 16:31:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个从typing.Generic继承并传入一个TypeVar作为参数的类

在代码的后面,我想:

  1. 静态地(不是在运行时)从类中获取TypeVar参数
  2. 将其别名为另一个类型变量
  3. 使用该别名键入函数的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


Tags: 方法fromimporttyping类型data参数return
1条回答
网友
1楼 · 发布于 2024-09-30 16:31:01

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

我想根据你的问题,你真正想要的是一种编写函数的方法,它接受一些BaseDataClass[T](或这种类型的子类),并返回任何T

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

在本例中,我们选择匹配BaseDataClass[T]类型的任何内容,其中我们将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

相关问题 更多 >