如何从 Generic 静态获取 TypeVar 参数以用于静态类型检查?
How to statically get TypeVar parameters from a Generic for use in static type checking?
我有一个class继承自typing.Generic
并传入一个TypeVar
作为参数。
稍后在代码中,我想:
- 静态地(不是在运行时)从 class
中获取 TypeVar
参数
- 将其别名为另一个类型变量
- 使用该别名键入函数的
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
然后我将 BaseDataClass
和 ChildDataClass
导入另一个模块。
在第二个模块中,有没有办法从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。
我有一个class继承自typing.Generic
并传入一个TypeVar
作为参数。
稍后在代码中,我想:
- 静态地(不是在运行时)从 class 中获取
- 将其别名为另一个类型变量
- 使用该别名键入函数的
return
提示
TypeVar
参数
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
然后我将 BaseDataClass
和 ChildDataClass
导入另一个模块。
在第二个模块中,有没有办法从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。