尝试在Python代码中使用静态类型,因此mypy
可以帮助我解决一些隐藏的错误。使用单个变量非常简单
real_hour: int = lower_hour + hour_iterator
更难以将它与列表和词典一起使用,需要导入额外的typing
库:
from typing import Dict, List
hour_dict: Dict[str, str] = {"test_key": "test_value"}
但主要问题 - 如何使用不同值类型的Dicts,如:
hour_dict = {"test_key": "test_value", "test_keywords": ["test_1","test_2"]}
如果我不对这样的词典使用静态类型 - mypy会显示错误,例如:
len(hour_dict['test_keywords'])
- Argument 1 to "len" has incompatible type
那么,我的问题是:如何在这些词典中添加静态类型? :)
你需要某种Union
类型。
from typing import Dict, List, Union
# simple str values
hour_dict: Dict[str, str] = {"test_key": "test_value"}
# more complex values
hour_dict1: Dict[str, Union[str, List[str]]] = {
"test_key": "test_value",
"test_keywords": ["test_1","test_2"]
}
一般来说,当你需要“这个或那个”时,你需要一个Union
。在这种情况下,您的选项是str
和List[str]
。
有几种方法可以解决这个问题。例如,您可能希望定义类型名称以简化内联类型。
OneOrManyStrings = Union[str, List[str]]
hour_dict2: Dict[str, OneOrManyStrings] = {
"test_key": "test_value",
"test_keywords": ["test_1","test_2"]
}
我也可能建议简单性,平行性和规律性使所有dict
值纯粹List[str]
,即使只有一个项目。这将允许您始终获取值的len()
,而无需事先进行类型检查或保护条件。但这些点是尼特和调整。
虽然使用Union
确实是一种方法,但更精确的解决方案是使用(当前实验性的)TypedDict
类型,它允许您为每个字符串键分配特定类型。
要使用此类型,必须先使用pip安装mypy_extensions
第三方库。然后,您可以执行以下操作:
from typing import List
from mypy_extensions import TypedDict
MyDictType = TypedDict('MyDictType', {
'test_key': str,
'test_keywords': List[str],
})
hour_dict: MyDictType = {
"test_key": "test_value",
"test_keywords": ["test_1","test_2"]
}
请注意,我们需要明确表示hour_dict
类型为MyDictType
。稍微更简洁的方法是使用MyDictType
作为构造函数 - 在运行时,MyDictType(...)
完全等同于执行dict(...)
,这意味着下面的代码与上面的代码完全相同:
hour_dict = MyDictType(
test_key="test_value",
test_keywords=["test_1","test_2"]
)
最后,请注意使用TypedDict有一些限制:
Dict[...]
。(TypedDict
旨在使编写序列化/反序列化逻辑时更容易使用JSON blob / dicts,这就是这些约束的原因。)