[英]How to write type hints for a function returning itself?
from typing import Callable
def f() -> Callable:
return f
How to explicitly define f
's type?如何显式定义
f
的类型? like Callable[[], Callable]
像
Callable[[], Callable]
I think it is slightly like a linked list, but I can't implement it.我觉得它有点像一个链表,但我无法实现它。
from typing import Union
class Node:
def __init__(self, val):
self.val = val
self.next: Union[Node, None] = None
Ideally, you could use typing.Literal
to specify the exact function being returned, but that doesn't work for a number of reasons:理想情况下,您可以使用
typing.Literal
来指定返回的确切函数,但由于多种原因,这不起作用:
There's no way to refer to f
using typing.Literal
.没有办法使用
typing.Literal
来引用f
。 typing.Literal['f']
is the string literal 'f'
, not a forward reference to the function about to be defined. typing.Literal['f']
是字符串文字'f'
,而不是对即将定义的函数的前向引用。
f
doesn't necessarily refer to the function being defined. f
不一定是指正在定义的函数。 It's a free variable that could refer to something else entirely by the time the function is actually called.它是一个自由变量,可以在实际调用函数时完全引用其他内容。
OK, let's loosen our restriction.好的,让我们放宽限制。 Let's try to define a type of function that returns a function of its own type.
让我们尝试定义一个函数类型,它返回一个它自己类型的函数。 We can at least write a valid type hint:
我们至少可以写一个有效的类型提示:
T = typing.Callable[[],'T']
def f() -> T:
return f
but this is only useful as documentation;但这仅作为文档有用;
mypy
doesn't yet know how to handle recursively defined types like this. mypy
还不知道如何处理这样递归定义的类型。
So let's try所以让我们试试
T1 = Callable[[], 'T2']
T2 = Callable[[], T1]
def f() -> T2:
return f
Oops, mypy
doesn't like cyclic definitions, either.糟糕,
mypy
也不喜欢循环定义。
So we're left with your original idea, of using the overlay broad type of functions that take no arguments and returns some callable.因此,我们保留了您最初的想法,即使用覆盖范围广泛的不带参数并返回一些可调用函数的函数。
def f() -> Callable[[], Callable]:
return f
The problem with the comparison to Node
is that there's no type-level recursion involved;与
Node
比较的问题是不涉及类型级递归; next
simply refers to some value of type Node
. next
只是引用Node
类型的某个值。
I think @chepner's answer is great.我认为@chepner 的回答很棒。 If you really do want to express this as a recursive Callable type, then you could restructure the function as a callable class and do something like this:
如果您确实想将其表示为递归 Callable 类型,那么您可以将该函数重组为一个可调用类并执行如下操作:
from __future__ import annotations
class F:
def __call__(self) -> F:
return self
f = F()
You can test this with mypy to see that it maintains its type on future calls:您可以使用 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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.