Optional[...]是的简写表示法
Union[..., None],它告诉类型检查器特定类型的对象是必需的 还是
None必需的。
...代表 任何有效的类型提示
,包括复杂的复合类型或
Union[]更多类型。只要您有带有默认值的关键字参数
None,就应该使用
Optional。
因此,对于您的两个示例,您有
dict和
list容器类型,但是
a关键字参数的默认值也显示了
None允许的值,因此请使用
Optional[...]:
from typing import Optionaldef test(a: Optional[dict] = None) -> None: #print(a) ==> {'a': 1234} #or #print(a) ==> Nonedef test(a: Optional[list] = None) -> None: #print(a) ==> [1, 2, 3, 4, 'a', 'b'] #or #print(a) ==> None请注意,在技术上是使用没有任何区别
Optional[]上
Union[],或者只是添加
None到
Union[]。所以
Optional[Union[str,int]]和
Union[str, int, None]完全一样。
就个人而言,在设置用于设置默认值的关键字参数的类型时,我 始终
坚持使用,这说明了允许更好的原因。而且,它使将零件移到单独的类型别名中或在自变量变为必需的情况下以后更容易删除零件变得更加容易。
Optional[]``=None``None``Union[...]``Optional[...]
例如,说你有
from typing import Optional, Uniondef api_function(optional_argument: Optional[Union[str, int]] = None) -> None: """Frob the fooznar. If optional_argument is given, it must be an id of the fooznar subwidget to filter on. The id should be a string, or for backwards compatibility, an integer is also accepted. """
然后通过将
Union[str, int]类型拉入类型别名来改进文档:
from typing import Optional, Union# subwidget ids used to be integers, now they are strings. Support both.SubWidgetId = Union[str, int]def api_function(optional_argument: Optional[SubWidgetId] = None) -> None: """Frob the fooznar. If optional_argument is given, it must be an id of the fooznar subwidget to filter on. The id should be a string, or for backwards compatibility, an integer is also accepted. """
将迁移
Union[]到别名的重构变得更加容易,因为
Optional[...]使用代替了
Union[str, int,None]。
None毕竟,该值不是“ subwidget id”,也不是该值的一部分,
None它旨在标记不存在值。
旁注:除非您的代码仅需要支持Python
3.9或更高版本,否则您要避免在类型提示中使用标准库容器类型,因为您无法说明它们必须包含哪些类型。因此,分别使用和代替
dict和。当仅从容器类型
读取 时,您也可以接受任何不可变的抽象容器类型。列表和元组对象,同时是一个类型:
list``typing.Dict``typing.List
__
Sequence``dict``Mapping
from typing import Mapping, Optional, Sequence, Uniondef test(a: Optional[Mapping[str, int]] = None) -> None: """accepts an optional map with string keys and integer values""" # print(a) ==> {'a': 1234} # or # print(a) ==> Nonedef test(a: Optional[Sequence[Union[int, str]]] = None) -> None: """accepts an optional sequence of integers and strings # print(a) ==> [1, 2, 3, 4, 'a', 'b'] # or # print(a) ==> None在Python 3.9及更高版本中,所有标准容器类型均已更新以支持在类型提示中使用它们,请参阅PEP
585。 但是 ,虽然您现在 可以 使用
dict[str,int]或
list[Union[int,str]],但是您仍然可能希望使用更具表现力的
Mapping和
Sequence注释来指示函数不会改变内容(它们被视为“只读”),并且这些函数可以与分别充当映射或序列的
任何 对象。



