Python 键入 returns None 的函数,如果列表 arg 仅包含 None
Python typing for function that returns None if list arg only contains None
我正在使用一个有点像这样的函数(超级简化,例如):
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)
如果我调用该函数使用:
foo(*[1, 2, 3])
,我希望将 return 类型推断为 int
。
foo(*[None, None])
,我希望将 return 类型推断为 None
。
foo(*[1, None])
,梦会推算到int
,但如果None | int
. 就可以了
我试过泛型/重载,但我无法弄清楚这个谜题。我怎样才能做到这一点?
解决方法:
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
我正在使用一个有点像这样的函数(超级简化,例如):
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)
如果我调用该函数使用:
foo(*[1, 2, 3])
,我希望将 return 类型推断为int
。foo(*[None, None])
,我希望将 return 类型推断为None
。foo(*[1, None])
,梦会推算到int
,但如果None | int
. 就可以了
我试过泛型/重载,但我无法弄清楚这个谜题。我怎样才能做到这一点?
解决方法:
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