我应该如何使用可选的类型提示?

2024-06-07 10:08:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图理解如何使用Optional类型提示。从PEP 434,我知道我可以使用Optional作为def test(a: Union[int, None])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[]


Tags: ortestnone类型deftypeoptionaldict
1条回答
网友
1楼 · 发布于 2024-06-07 10:08:58

Optional[...]Union[..., None]的简写符号,告诉类型检查器需要特定类型的对象,None是必需的。...表示任何有效的类型提示,包括复杂的复合类型或更多类型的Union[]。当您有一个默认值为None的关键字参数时,应该使用Optional

因此对于您的两个示例,您有dictlist容器类型,但是a关键字参数的默认值表明None也被允许,因此使用Optional[...]

from typing import Optional

def test(a: Optional[dict] = None) -> None:
    #print(a) ==> {'a': 1234}
    #or
    #print(a) ==> None

def test(a: Optional[list] = None) -> None:
    #print(a) ==> [1, 2, 3, 4, 'a', 'b']
    #or
    #print(a) ==> None

请注意,在Union[]上使用Optional[]与在Union[]中添加None在技术上没有区别。所以Optional[Union[str, int]]Union[str, int, None]是完全相同的。

就我个人而言,在设置使用= None设置默认值的关键字参数的类型时,我会坚持使用Optional[]始终使用^{,这说明了为什么更好地允许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

# 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值毕竟不是“子窗口小部件id”,它不是值的一部分,None是用来标记缺少值的。

附带说明:您希望避免在类型提示中使用标准库容器类型,因为您无法说明它们必须包含哪些类型;因此,使用typing.Listtyping.Dict代替dictlist。当只从容器类型中读取时,也可以接受任何不可变的抽象容器类型;列表和元组是Sequence对象,而dictMapping类型:

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"""
    # print(a) ==> {'a': 1234}
    # or
    # print(a) ==> None

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

相关问题 更多 >

    热门问题