如何处理 "incompatible type "Optional[str]"; expected "str""?

How to deal with "incompatible type "Optional[str]"; expected "str""?

假设我有这样的代码结构

from __future__ import annotations
from typing import TypedDict


class ValDict(TypedDict):
    something: str
    a: A


class A:
    def __init__(self, x: str) -> None:
        if x and isinstance(x, str):
            self.x = x
        else:
            raise ValueError("x has to be a non-empty string")


class B:
    def __init__(self, something: str, a: A) -> None:
        self.something = something
        if isinstance(a, A):
            self.a = a
        else:
            raise ValueError("a has to be of type A")

    @classmethod
    def from_dict(cls, stuff: ValDict) -> B:
        something = stuff.get('something')
        a = stuff.get('a')

        return cls(something, a)

我 运行 mypy 对此,我会收到 2 个错误

error: Argument 1 to "B" has incompatible type "Optional[str]"; expected "str"

error: Argument 2 to "B" has incompatible type "Optional[A]"; expected "A"

错误很明显:由于 .get 也可以 return None,我可能无法将正确的类型传递给 [=18] 中的 cls 调用=]方法。

我的问题是如何避免它。对于参数 something 我可能会修改为

something = stuff.get('something', '')

但是我将如何处理 a 的情况?有什么想法吗?

我会完全放弃使用 get,直接访问密钥。当然,这会引发 KeyError,但是如果您传入 A.

实例以外的任何内容,class 无论如何都无法正确初始化

可以 有一个 A 的“默认实例”,只要它不在 stuff 中就可以使用,但是从你的 B.__init__ 来看你似乎不需要默认参数。

所以方法会变成:

@classmethod
def from_dict(cls, stuff: ValDict) -> B:
    something = stuff['something']
    a = stuff['a']

    return cls(something, a)

这样,可以发生三件事:

  • stuff 具有正确的键和值 -> B 已初始化
  • stuff 没有正确的密钥 -> B.from_dict
  • 上的 KeyError
  • stuff 具有正确的键,但键 "a" 的值类型不正确 -> ValueError on B.__init__