排除Python类型注释中的类型

23

我编写了下面的函数:

def _clean_dict(d):
    return {k: v for k, v in d.items() if v is not None}

我想给这个函数添加类型注释:

def _clean_dict(d: Dict[Any, Any]) -> Dict[Any, Any]:                           
    return {k: v for k, v in d.items() if v is not None}

然而,我想明确指出返回的字典中的值不能为 None。

有没有一种方式可以说“除了NoneType之外的Any类型”或“任何可能的值,但不包括None”?


你实际上并不是通过类型提示来强制返回类型。类型提示的存在是为了当你从其他地方引用代码时,可以发现函数应该返回什么。由编写代码的人来确保函数返回适当的值(如果它返回任何值)。 - MurrayW
2
我并没有询问如何强制执行类型,只是希望注释明确表明返回的字典值中不应该有None/NoneType - Yam Mesicka
啊,我的错误。你可以通过函数文档字符串将此添加为注释吗? - MurrayW
2
我可以这样做,但我确实认为应该有一种使用类型提示的方法,就像你可以使用 Optional 来表示某些内容可以为 None 一样。 - Yam Mesicka
1
从代码中看来,很明显这些值不能为None,因为在字典推导式中已经明确说明了。正如@MurrayW所说,注释或文档字符串是人们使用的方法。 - QuantumChris
2个回答

7

Python类型提示无法排除类型。无法排除Nonestr或任何其他类型。

唯一可以用来尝试模拟排除None的方法是使用Union,并在字典中写出实际使用的每种类型。


4
Python支持不了的原因是什么? - laike9m
需要注意的是,即使使用了Union方法,类型检查器仍然允许出现None。Mypy有一个strict_optional标志可以关闭此行为,但这会使其与大多数现有的Python代码不兼容。 - Simon
讨论在此处:https://github.com/python/typing/issues/256 - Alexander McFarlane

7

如果您希望在函数调用时修复键和值的类型,您可以使用泛型使其明确。这仍然可能允许V的实例为None,但它使意图非常清晰。请注意,由于变异问题,必须使用Mapping。但是,这样做更好。

from typing import *


K = TypeVar("K")
V = TypeVar("V")


def _clean_dict(d: Mapping[K, Optional[V]]) -> MutableMapping[K, V]:
    return {k: v for k, v in d.items() if v is not None}

使用此定义,mypy 可以将可选类型正确地转换为非可选类型。

# clean_dict.py

d = {"a": 1, "b": 2, "c": None}
reveal_type(d)
reveal_type(_clean_dict(d))

$ mypy clean_dict.py

note: Revealed type is 'builtins.dict[builtins.str*, Union[builtins.int, None]]'
note: Revealed type is 'typing.MutableMapping[builtins.str*, builtins.int*]'


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接