[英]Python typing for function that returns None if list arg only contains None
我正在使用有点像这样的 function(超级简化,例如):
def foo(*stuff: None | int):
stuff_not_none = [x for x in stuff if x is not None]
if len(stuff_not_none) is 0:
return None
return sum(stuff_not_none)
如果我使用以下方式调用 function:
foo(*[1, 2, 3])
,我希望将返回类型推断为int
。foo(*[None, None])
,我希望将返回类型推断为None
。foo(*[1, None])
,梦想将被推断为int
,但如果None | int
就可以了 None | int
。我试过 generics / 重载,但我无法弄清楚这个谜题。 我怎样才能做到这一点?
解决方案:
from typing import overload
@overload
def foo(*stuff: None) -> None: ... # type: ignore[misc]
@overload
def foo(*stuff: int | None) -> int: ...
def foo(*stuff: int | None) -> int | None:
stuff_not_none = [x for x in stuff if x is not None]
if len(stuff_not_none) is 0:
return None
return sum(stuff_not_none)
reveal_type(foo(None, None)) # revealed type is None
reveal_type(foo(1, 2, 3)) # revealed type is int
reveal_type(foo(None, 2, None, 4)) # revealed type is int
foo('a', 'b') # error: no matching overload
Mypy讨厌这种事情,因为重载重叠。 但是你会发现,如果你在正确的地方添加了type: ignore
注释,它无论如何都完全能够推断出正确的类型。 (我是一个 typeshed 维护者,我们一直在 typeshed 做这种事情。)
请注意,重载的顺序非常重要:类型检查器将始终首先尝试第一个重载,然后,只有当它不匹配时,他们才会尝试第二个重载。 当我们传入int
s 和None
s 的混合时,这就是我们如何获得int
显示类型:第一个重载不匹配,因为存在int
s,所以类型检查器被迫尝试第二个重载。
Mypy 游乐场演示: https://mypy-play.net/?mypy=latest&python=3.10&gist=ff07808e0a314208fdfa6291dcf9f717
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.