Optional[...]
是的简写表示法Union[..., None]
,它告诉类型检查器特定类型的对象是必需的还是 None
必需的。...
代表任何有效的类型提示,包括复杂的复合类型或Union[]
更多类型。只要您有带有默认值的关键字参数None
,就应该使用Optional
。
因此,对于您的两个示例,您有dict
和list
容器类型,但是a
关键字参数的默认值也显示了None
允许的值,因此请使用Optional[...]
:
from typing import Optional
def test(a: Optional[dict] = None) -> None:
def test(a: Optional[list] = None) -> None:
请注意,在技术上是使用没有任何区别Optional[]
上Union[]
,或者只是添加None
到Union[]
。所以Optional[Union[str, int]]
和Union[str, int, None]
完全一样。
就个人而言,在设置用于设置默认值的关键字参数的类型时,我始终坚持使用,这说明了允许更好的原因。而且,它使将零件移到单独的类型别名中或在参数变为强制性的情况下稍后删除零件时变得更加容易。Optional[]
= None
None
Union[...]
Optional[...]
例如,说你有
from typing import Optional, Union
def 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
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, Union
def test(a: Optional[Mapping[str, int]] = None) -> None:
"""accepts an optional map with string keys and integer values"""
def 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
注释来指示函数不会改变内容(它们被视为“只读”),并且该函数可以与分别充当映射或序列的任何对象。
Dict
,List
键入和写入Optional[Dict]
,Optional[List]
而不是Optional[dict]
...