如何为返回自身的函数编写类型提示


from typing import Callable

def f() -> Callable:
return f

如何显式定义f的类型?如Callable[[], Callable]

我认为它有点像一个链表,但我无法实现它

from typing import Union

class Node:
def __init__(self, val):
self.val = val
self.next: Union[Node, None] = None

我认为@chepner的回答很好。如果您真的想将其表示为递归可调用类型,那么您可以将函数重新构造为可调用类,并执行以下操作:

from __future__ import annotations

class F:
def __call__(self) -> F:
return self

f = F()

你可以用mypy测试它,看看它在未来的调用中是否保持其类型:

g = f()
h = g(1)  # Too many arguments for "__call__" of "F"
i = h()
j = i(2)  # Too many arguments for "__call__" of "F"
k = j()

理想情况下,您可以使用typing.Literal来指定返回的精确函数,但这不起作用,原因有很多:

  1. 使用typing.Literal无法引用ftyping.Literal['f']是字符串文字'f',而不是对即将定义的函数的前向引用。

  2. f不一定指正在定义的函数。它是一个自由变量,在实际调用函数时,它可能完全引用其他内容。

好吧,让我们放松限制。让我们尝试定义一种函数类型,它返回自己类型的函数。我们至少可以写一个有效的类型提示:

T = typing.Callable[[],'T']
def f() -> T:
return f

但这仅作为文档有用;mypy还不知道如何处理像这样递归定义的类型。

所以让我们试试

T1 = Callable[[], 'T2']
T2 = Callable[[], T1]
def f() -> T2:
return f

糟糕的是,mypy也不喜欢循环定义。

因此,我们只剩下您最初的想法,即使用覆盖广泛类型的函数,这些函数不带参数,并返回一些可调用的函数。

def f() -> Callable[[], Callable]:
return f

Node的比较问题在于不涉及类型级递归;next简单地指Node类型的一些值。

最新更新