我的 TypeVar
定义有问题。
我的函数需要一个元组的元组作为参数。主元组可以有和组件一样多的元组,但它们之间不必共享相同的类型。
但是主元组中元组的组件必须共享相同的类型。
这里是一个简化的代码示例:
以下代码在 python 中工作,但我在 Pycharm 中有警告
form((("prompt", str, "default"),
("prompt", int, 10),
("prompt", str, "default"),
("prompt", float, .5)))
我这样定义我的函数:
ValueType = TypeVar('ValueType', str, int, float, bool)
InputDefinitionType = Tuple[str, Type[ValueType], ValueType]
def form(input_def: Tuple[InputDefinitionType, ...])
...
如何“重置”TypeVar 组以仅匹配包含在主元组内的元组内的类型但不跨越主元组本身?
最佳答案
tl;dr:您实现它的方式是错误的,但在这个答案的底部有一个解决方法。
不幸的是,您的代码没有类型检查。受约束的类型变量必须引用给定“范围”内的相同类型(PEP 484 对范围有一些定义,但不太精确)。
在您的情况下,ValueType
必须引用 form
函数中的单一类型,因此您的调用无效。
至于为什么代码似乎在 mypy 中进行了类型检查,这是因为 InputDefinitionType
是一个 generic type alias ,但您在没有参数化的情况下使用它,这相当于使用 Any
进行参数化。简单地说:
def form(input_def: Tuple[InputDefinitionType, ...]) -> None: ...
相当于
def form(input_def: Tuple[InputDefinitionType[Any], ...]) -> None: ...
您可以在 mypy-play 中看到这个,其中最后的 reveal_type(form)
显示了函数的推断类型:
main.py:15: note: Revealed type is "def (input_def: builtins.tuple[Tuple[builtins.str, Type[Any], Any]])"
一个解决方法是将它变成一个 Union
类型:
ValueType = TypeVar('ValueType')
InputDef = Tuple[str, Type[ValueType], ValueType] # name shortened for conciseness
InputDefConcrete = Union[
InputDef[float], InputDef[str], InputDef[bool], InputDef[int]
]
def form(input_def: Tuple[InputDefConcrete, ...]) -> None: ...
在 mypy-play 上查看实际效果.
关于元组中的python TypeVar重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68869338/