Python class 成员的类型提示 None 类型或字典

Python type hint for class member with None type or dict

我有 class 个成员,它是 Nonedict。 如果 returns None 成员的长度 成员是 None 或字典的大小(如果存在):

class A:
    def __init__(self, a: bool = False) -> None:
        self.has_a = a
        self.prop_a = {"a" : 1} if a else None

    def length_prop(self) -> int:
        length_prop = None
        if self.has_a:
            length_prop = len(self.prop_a)
        return length_prop

如果我用 mypy 检查输入:

test.py:10: error: Argument 1 to "len" has incompatible type "Optional[Dict[str, int]]"; expected "Sized"
                length_prop = len(self.prop_a)
                                  ^
test.py:11: error: Incompatible return value type (got "Optional[int]", expected "int")
            return length_prop

很好理解,因为它不知道 self.prop_a 是否真的是 dict。 我如何设计我的代码来解决这个问题并获得正确的输入?

有两个问题:

  1. mypy 不能也不应该跨函数推断 has_aprop_a 之间的关系。 您需要在 length_prop 函数中包含对 None 的显式检查。这个错误不是虚假的——例如,如果一些外部代码修改了 has_a 而不是 prop_a 的值会发生什么?

    最简单的解决方案是取消 has_a 字段,因为它编码的所有信息都可以通过检查 prop_a(例如,prop_a is not None)来检索.

  2. length_prop的return值可以是None,所以用Optional[int]而不是int 用于 length_prop 方法。

以下代码片段解决了这两个问题。 mypy 在此 class 定义中未发现任何错误:

from typing import Optional

class A:
    def __init__(self, a: bool = False) -> None:
        self.prop_a = {"a" : 1} if a else None

    def length_prop(self) -> Optional[int]:
        length_prop = None
        if self.prop_a is not None:
            length_prop = len(self.prop_a)
        return length_prop

在Python3.10中,可以使用Dict[str, int]| None,否则可以使用Union[Dict[str, int], None]

您还需要检查对象是否不是 None 到 return 正确的值(可能引发异常或 return 负值)