在Python中定义递归类型提示?

60

假设我有一个函数,接受一个Garthok、一个Iterable[Garthok]、一个Iterable[Iterable[Garthok]]等。

def narfle_the_garthoks(arg):
  if isinstance(arg, Iterable):
    for value in arg:
       narfle_the_garthoks(arg)
  else:
    arg.narfle()

有没有一种方法可以指定参数的类型提示,表明它接受任何级别的GarthokIterable?我怀疑没有,但是想检查一下是否遗漏了什么。

作为解决方法,我只是指定了几个深度级别,然后以 Iterable[Any] 结束。

Union[Garthok,
    Iterable[Union[Garthok,
        Iterable[Union[Garthok, 
            Iterable[Union[Garthok, Iterable[Any]]]]]]]]

这个回答解决了你的问题吗?递归类型注释 - Georgy
2个回答

80

啊,明白了。谢谢!看起来IDEA/PyCharm也不支持它。 - JesusFreke
1
@DanielH 类是类型。您还可以使用 TypeVars 并子类化 Generic 来使用那个 [] 语法。 - gilch
@DanielH 是的,我没有看到类似的东西。但是作为一个额外的奖励,在浏览打字文档时,我刚刚发现了无关的 @typing.overload 装饰器,这是我需要的另一件事 :D - JesusFreke
2
某些类型的前向引用由PEP0563处理。您可以通过执行from __future__ import annotations从Python 3.7开始使用它们。 - Konstantin
2
不幸的是,无法编写NestedList = list[str |“NestedList”]而不是NestedList = list[Union[str,“NestedList”]],因为它会引发TypeError:unsupported operand type(s) for |: 'type' and 'str' - d-k-bo
显示剩余4条评论

-1

MyPy存在这个限制,它还不支持循环引用,但我找到了一种使用TypeVars的方法来解决它:

from typing import TypeVar, TypeAlias, Iterable, Union

T = TypeVar('T')
_Garthoks: TypeAlias = Union[T, Iterable[T]]
Garthoks: TypeAlias = _Garthoks[_Garthoks[_Garthoks[_Garthoks]]]
# you can nest it as deep as you need...

目前,我认为这是最好的解决方案,因为MyPy支持此功能。

希望它能解决你的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接