【问题标题】:Exclude type in Python typing annotation在 Python 类型注释中排除类型
【发布时间】:2021-12-11 23:46:41
【问题描述】:

我写了以下函数:

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}

但是,我想明确定义返回字典中的值不能为无。

有没有办法说“Any 类型,NoneType 除外”或“除None 之外的所有可能值”?

【问题讨论】:

  • 您实际上并没有通过类型提示强制返回类型。存在类型提示,因此当您从其他地方引用代码时,您可以发现期望函数返回的内容。由谁编写代码来确保函数返回适当的值(如果它返回任何东西)。
  • 我没有询问强制类型。只是希望注释明确显示返回字典的值中不应有None/NoneType。
  • 啊,我的错。您可以通过函数文档字符串将其添加为注释?
  • 我可以,但我确实认为应该有一种使用类型提示的方法来做到这一点,就像您可以使用 Optional 来显示某些东西可以是 None 一样。
  • 从代码中可以明显看出这些值不能是None,因为它在字典理解中明确说明。正如@MurrayW 所说,评论或文档字符串将是人们会使用的。

标签: python python-3.x type-hinting mypy python-typing


【解决方案1】:

Python 类型提示不能排除类型。您不能排除 Nones、strs 或任何其他类型。

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

【讨论】:

  • 有什么理由Python不支持?
  • 应该注意,即使使用Union 方法,类型检查器仍将允许None。 Mypy 有 strict_optional 标志来关闭此行为,但这使其与大多数现有 Python 代码不兼容。
【解决方案2】:

鉴于您愿意在调用函数时修复键和值的类型,您可以使用泛型来明确这一点。这仍然可能允许V 的实例成为None,但它的意图非常明确。请注意,由于variance issues,您必须使用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*]'

【讨论】:

    猜你喜欢
    • 2016-04-02
    • 1970-01-01
    • 2022-11-15
    • 2021-10-22
    • 1970-01-01
    • 2021-11-12
    • 2021-09-13
    • 2018-08-01
    相关资源
    最近更新 更多