【发布时间】: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