这几天在阅读一段源代码时,突然看到了这样的写法:
1 | class A: |
当时一愣——这三个点是个什么玩意儿,好像只在 numpy
中切片时用过,怎么突然出现在这里?嗯,于是就有了这篇小文,记录下这个有意思的玩意儿。总的来说,主要有以下几种用法:
- Numpy Slice:表示「其他维度的所有值」
- 类型提示:表示「不指定、可变的、任意的」参数类型
- 占位符:表示类或方法还没写的 Body
- 循环引用:表示一个循环引用,而不是满屏幕打印
- 特殊标记:表示一个特殊的位置,比如结束、开始等
首先,这三个点有个学名,叫「Ellipsis」,我们在 Python 中简单执行下:
1 | ... |
...
在 Python 中就等价于 Ellipsis
,类型是 ellipsis
。根据在 CPython
源码中的定义,可知它是一个单例:
1 | class Ellipsis(Constant, metaclass=_ABC): |
接下来就看它常用在哪些地方。
Numpy切片
这个应该是比较熟悉的了,在索引时,...
往往表示「其他所有维度的值」。先随机生成一个多维矩阵:
1 | import numpy as np |
然后进行切片:
1 | arr[...] == arr |
使用起来非常方便简洁。
类型提示
类型提示是 Python3.5 开始有的新功能,借鉴自静态语言,主要是对函数或类的参数和返回值类型进行标记,便于代码阅读。...
在其中主要表达「可变或动态提示」,下面用一个例子来说明。
1 | def demo( |
Callable
提示中第一个表示输入的参数类型,第二个是返回值的类型。
- 如果
Callable
「参数提示」使用...
,则表示不指定输入的参数类型 - 如果「参数类型」使用
[type, ...]
,则表示参数是变长的,这个经常会用在Tuple
里 - 如果「参数或返回值的类型提示」使用
...
,则表示该参数或返回值是任意类型的,与Any
等价 - 如果「参数的默认值」使用
...
,则表示该参数默认值为Ellipsis
,当想区分不传入值或传入None
时比较有用
占位符
与 pass
一样的功能,当我们在不关心实现细节,快速搭建代码框架时经常会用到:
1 | def run(): |
循环引用
当创建一个循环引用时,Python 会使用 ...
显示无限循环,注意,这并不是真的替换了引用。
1 | a = [0, 1] |
特殊标记
有时候会用来当做队列结束的标记,比如:
1 | q = [1, 2, 3, ...] |
这很容易理解,因为我们既不需要新建一个对象专门作为标记,...
又足够特殊,一般队列的值不会是它。
参考资料