我试图了解如何使用 Optional
类型提示。 From PEP-484 , I know I can use Optional
for def test(a: int = None)
either as def test(a: Union[int, None])
or def test(a: Optional[int])
.
但是下面的例子怎么样?
def test(a : dict = None):
#print(a) ==> {'a': 1234}
#or
#print(a) ==> None
def test(a : list = None):
#print(a) ==> [1,2,3,4, 'a', 'b']
#or
#print(a) ==> None
如果 Optional[type]
似乎与 Union[type, None]
意思相同,我为什么要使用 Optional[]
呢?
原文由 jacobcan118 发布,翻译遵循 CC BY-SA 4.0 许可协议
Optional[...]
是Union[..., None]
的简写符号,告诉类型检查器需要特定类型的对象, 或者 需要None
...
代表 _任何有效的类型提示_,包括复杂的复合类型或更多类型的Union[]
。每当你有一个默认值None
的关键字参数时,你应该使用Optional
。 (注意:如果您的目标是 Python 3.10 或更新版本, PEP 604 引入了更好的语法,请参见下文)。So for your two examples, you have
dict
andlist
container types, but the default value for thea
keyword argument shows thatNone
也被允许使用Optional[...]
:There is technically no difference between using
Optional[]
on aUnion[]
, or just addingNone
to theUnion[]
.所以Optional[Union[str, int]]
和Union[str, int, None]
是完全一样的东西。就个人而言,我会坚持 始终 使用
Optional[]
为使用= None
设置默认值的关键字参数设置类型时,这记录了为什么None
允许更好。此外,它更容易将Union[...]
部分移动到单独的类型别名中,或者如果参数成为强制性的,则稍后删除Optional[...]
部分。例如,假设你有
然后通过将
Union[str, int]
拉出到类型别名中来改进文档:将
Union[]
移动到别名中的重构变得更加容易,因为使用Optional[...]
而不是Union[str, int, None]
None
值毕竟不是“subwidget id”,它不是值的一部分,None
是为了标记值的缺失。旁注:除非您的代码只需要支持 Python 3.9 或更新版本,否则您希望避免在类型提示中使用标准库容器类型,因为您无法说明它们必须包含哪些类型。因此,代替
dict
typing.Dict
list
typing.List
当仅从容器类型 读取 时,您也可以接受任何不可变的抽象容器类型;列表和元组是Sequence
对象,而dict
是Mapping
类型:在 Python 3.9 及更高版本中,标准容器类型已全部更新以支持在类型提示中使用它们,请参阅 PEP 585 。 But , while you now can use
dict[str, int]
orlist[Union[int, str]]
, you still may want to use the more expressiveMapping
andSequence
annotations to indicate一个函数不会改变内容(它们被视为“只读”),并且这些函数将分别与 任何 作为映射或序列工作的对象一起工作。Python 3.10 将
|
联合运算符引入到类型提示中,请参阅 PEP 604 。而不是Union[str, int]
你可以写str | int
。与其他类型提示语言一致,在 Python 3.10 及更高版本中表示可选参数的首选(且更简洁)方式现在是Type | None
,例如str | None
或list | None
。