【问题标题】:mypy: define types for specific keys in dynamic dictionarymypy:为动态字典中的特定键定义类型
【发布时间】:2019-06-20 00:13:04
【问题描述】:

我有以下字典,代表一个可能是许多变体之一的人。这里只是一些:

person = {"name": "Johnny"}
person = {"name": "Johnny", "age": 25}
person = {"name": "Johnny", "age": 25, "active": True}

我正在提取某些键并使用它们来打印语句。问题出现在类型提示中,当我在脚本上运行 mypy 时,我收到一条错误消息 Incompatible types in assignment (expression has type "object", variable has type "Optional[str]")

name: Optional[str] = person.get("name")  # mypy error here
age: Optional[int] = person.get("age")    # mypy error here
if name and age:
    print(f"In 5 years, {name} will be {age + 5} years old")

要解决这个问题,mypy_extensions.TypedDict 类型似乎很有希望,但似乎我不能缺少或多余的键:

from mypy_extensions import TypedDict
PersonDict = TypedDict("PersonDict", {"name": str, "age": int})

# ERROR: Key 'age' missing for TypedDict "PersonDict"
person: PersonDict = {"name": "Johnny"}

# ERROR: Extra key 'active' for TypedDict "PersonDict"
person: PersonDict = {"name": "Johnny", "age": 25, "active": True}

有没有为字典中的特定键定义类型,即使该字典中的键是动态的?

【问题讨论】:

  • 我有点困惑。 Mypy 告诉你,由于字典是动态的,任何get 都可能返回None,并且你应该将变量键入为Optional[str](即Union[None, str])。根据您的代码,这不完全正确吗?
  • @JoshKarpel mypy 没有将类型附加到字典中的 name 键;所以它假设它只是一个object,当我尝试给它一个Optional[str]
  • 那么你应该将字典声明为Dict[str, str],不是吗?
  • 啊,好点子。听起来你真的在与类型检查器作斗争——也许Person 应该是一个具有单独类型字段的类,可能是一个数据类。将 JSON 数据转换为数据类的层将是动态类型的,但是在将其转换为Person 之后,它可以是静态类型的。
  • 您可以将total=False 传递给TypedDict 构造函数以允许缺少键,但似乎不可能允许额外的键。

标签: python python-3.x mypy


【解决方案1】:

total=False 添加到您的 TypedDict 将允许缺少键:

PersonDict = TypedDict("PersonDict", {"name": str, "age": int}, total=False)

https://mypy.readthedocs.io/en/latest/more_types.html#totality

似乎不可能允许架构中没有的其他键。

【讨论】:

    猜你喜欢
    • 2020-08-31
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多