如何从泛型中静态获取TypeVar参数以用于静态类型检查? [英] How to statically get TypeVar parameters from a Generic for use in static type checking?

查看:74
本文介绍了如何从泛型中静态获取TypeVar参数以用于静态类型检查?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class that inherits from typing.Generic and passes in one TypeVar as the parameter.

稍后在代码中,我想:

  1. 通常(不在运行时)从类中获取 TypeVar 参数
  2. 将其别名为另一个类型变量
  3. 使用该别名键入提示功能的 return

Python中是否有某种方法可以实现这一目标?

Is there some way in Python that I can make this happen?

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

The only piece I am missing is step 1, how to get the type parameter out of a type variable

我的用例

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

然后我将 BaseDataClass ChildDataClass 导入另一个模块.

I then import BaseDataClass and ChildDataClass into another module.

在第二个模块中,有什么方法可以从 BaseDataClass 静态获取 TFloat 参数,或者从静态获取 int 参数ChildDataClass ,并在 mypy 中使用它?

In that second module, is there some way to statically get the TFloat parameter from BaseDataClass, or the int parameter from ChildDataClass, and use it in mypy?

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

FYI: I am using Python 3.8.2.

推荐答案

没有一种获取"类型变量的方法.您不应认为类型变量就像可以潜在地以某种方式提取的大量数据一样.而是将其视为定义的一部分.

There isn't a way of "getting" out a type variable. You shouldn't think of a type variable as being like a chunk of data you can potentially extract somehow. Instead, think of it as a part of a definition.

我认为,根据您的问题,您真正想得到的是一种编写接受某些 BaseDataClass [T] (或此类的子类)并返回任何 T 是.

I think based on your question, what you're really after is a way of writing a function that accepts some BaseDataClass[T] (or a subclass of this type) and returns whatever T is.

如果是这样,请创建一个匹配要定义的函数.但是,与其指定内部类型必须是特定的,不如使用泛型来捕获它.

If so, create a function that matches the definition of whatever you want to accept. But instead of specifying that the inner type must be something specific, capture it using a generic instead.

在这种情况下,我们选择与 BaseDataClass [T] 类型的任何内容进行匹配,在这里我们保持T泛型.我们的返回类型将是T碰巧匹配的任何类型.

In this case, we chose to match against anything of type BaseDataClass[T], where we keep T generic. And our return type will be whatever T happened to match up against.

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文档.

For more details and examples, see the mypy docs on generics.

这篇关于如何从泛型中静态获取TypeVar参数以用于静态类型检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆