元组中的python TypeVar重置

标签 python typing python-typing

我的 TypeVar 定义有问题。
我的函数需要一个元组的元组作为参数。主元组可以有和组件一样多的元组,但它们之间不必共享相同的类型。
但是主元组中元组的组件必须共享相同的类型。

这里是一个简化的代码示例:
以下代码在 python 中工作,但我在 Pycharm 中有警告

form((("prompt", str, "default"),
      ("prompt", int, 10),
      ("prompt", str, "default"),
      ("prompt", float, .5)))

PyCharm Warning

我这样定义我的函数:

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/

相关文章:

python - Python 函数定义中的列表构建

python - 在类型别名中使用泛型

python - 如何编写一个满足typing.TextIO 的类文件?

os.getenv 的 Python typehint 导致下游不兼容类型错误

python - 在统计注释中自定义 "star"文本格式的 p 值阈值

python - 如何确保脚本始终使用cron运行?

python - 如何让球像打乒乓球一样保持移动?

lua - Lua 中记录类型的约定是什么?

python - 为 Callable 类型提示指定 *args

python - Mypy:键入要加在一起的两个 int 或 str 列表