繁体   English   中英

Python 键入 function 如果列表 arg 仅包含 None 则返回 None

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM