Python 3:函数参数中的省略号?

问题描述 投票:0回答:2

我最近遇到了省略号(

...
),它在 aiohttp 代码中的函数参数中使用,然后在该函数的主体中使用:

def make_mocked_request(method, path, headers=None, *,
                        match_info=sentinel,
                        version=HttpVersion(1, 1), closing=False,
                        app=None,
                        writer=sentinel,
                        protocol=sentinel,
                        transport=sentinel,
                        payload=sentinel,
                        sslcontext=None,
                        client_max_size=1024**2,
                        loop=...):
    """Creates mocked web.Request testing purposes.

    Useful in unit tests, when spinning full web server is overkill or
    specific conditions and errors are hard to trigger.

    """

    task = mock.Mock()
    if loop is ...:
        loop = mock.Mock()
        loop.create_future.return_value = ()

你能解释一下这个新的 python 3 特性吗?

python python-typing
2个回答
42
投票

Ellipsis 是Python 中的内置常量。 在 Python 3 中,它具有文字语法

...
,因此可以像任何其他文字一样使用。这被 Python 3 的 Guido 接受,因为 有些人认为它很可爱

您找到的代码(用作函数参数默认值)显然是这样一种“可爱”的用法。稍后在该代码中您将看到:

if loop is ...:
    loop = mock.Mock()
    loop.create_future.return_value = ()

它在这里只是被用作哨兵,也可能是

object()
或其他任何东西 -
Ellipsis
没有什么特定的。也许通常的哨兵,
None
,在这种情况下有一些其他特定的含义,尽管我在提交中看不到任何证据(看起来
None
也同样有效)。

有时在野外看到的省略号文字的另一个用例是尚未编写的代码的占位符,类似于 pass 语句:

class Todo:
    ...

有关涉及扩展切片语法的更典型用例,请参阅Python Ellipsis 对象有什么作用?


8
投票

基于 https://stackoverflow.com/a/54406084/1988486 构建,使用

...
None
在处理类型注释时具有一定的有效性。考虑以下几点:

def foo(map: dict = None):
    if not map:
        map = {}

    return map

当然,这并没有多大作用,但这会导致类型提示在现代编辑器(例如 VS Code)中发生冲突。这是因为您声称

map
dict
,但默认值是
NoneType
(不是
dict
)。

省略号是它自己的类型,因此 VS Code 不会抱怨,但您可以以类似的方式与它交互,因为它是一个标记值。

def food(map: dict = ...):
    if map is ...:
        map = {}

    return map

VS Code 不会引起任何关于类型提示以及该变量在运行代码过程中可能变成的各种类型的担忧。

我无法确定为什么

aiohttp
代码使用它,因为它们似乎没有使用类型注释,但这至少是这样做的一个可行的理由。

© www.soinside.com 2019 - 2024. All rights reserved.