椭圆对象有什么作用?


539

在闲置地浏览命名空间时,我注意到一个看起来很奇怪的对象Ellipsis,它似乎并没有做任何特别的事情,但它是一个全局可用的内置对象。

经过搜索,我发现Numpy和Scipy在切片语法的某些晦涩变体中使用了它……但是几乎没有其他东西。

是否将此对象添加到专门支持Numpy + Scipy的语言中?Ellipsis是否有任何一般意义或用途?

D:\workspace\numpy>python
Python 2.4.4 (#71, Oct 18 2006, 08:34:43) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> Ellipsis
Ellipsis


19
我发现是这样的:输入x=[];x.append(x);print(x),以查看其如何处理循环对象的字符串化。它回来了[[...]]。我想:“我不知道会发生什么,如果我输入[[...]]我的猜测是它会抛出一个语法错误相反,它返回?[[Ellipsis]]Python是如此怪异随之而来把我带到这个网页的谷歌搜索。
Cyoce

22
请注意,...递归代表中的只是一个占位符,与Ellipsis
Eevee

16
完全顺便说一句,导入中的三点表示“从两个软件包导入”。
疯狂物理学家

1
@croq stackoverflow.com/q/32395926/2988730stackoverflow.com/q/1054271/2988730。这两个应该说明所有内容,并在答案中提供指向docs和PEP的正确链接。
疯狂物理学家

Answers:


557

这是最近另一个问题。我将从那里详细说明我的答案

省略号是可以以切片表示法显示的对象。例如:

myList[1:2, ..., 0]

它的解释完全取决于实现该__getitem__函数并在其中看到Ellipsis对象的任何事物,但是其主要(和预期的)用途是在numpy第三方库中,该库添加了多维数组类型。由于存在多个维度,因此切片变得比仅起始索引和终止索引更为复杂;能够在多个维度上切片也很有用。例如,给定一个4x4数组,左上方区域将由slice定义[:2,:2]

>>> a
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12],
       [13, 14, 15, 16]])

>>> a[:2,:2]  # top left
array([[1, 2],
       [5, 6]])

进一步扩展,此处省略号用于表示未指定的其余数组尺寸的占位符。可以认为它表示所[:]放置间隙中所有维度的完整切片,因此对于3d数组,与4d a[...,0]相同,同样是(但中间有许多冒号组成了完整数数组中的尺寸)。a[:,:,0]a[:,:,:,0]a[0,...,0]a[0,:,:,0]

有趣的是,在python3中,省略号文字(...)在slice语法之外可用,因此您实际上可以编写:

>>> ...
Ellipsis

除了各种数字类型,不,我认为它没有被使用。据我所知,它纯粹是为numpy使用而添加的,除了提供对象和相应的语法外,没有其他核心支持。那里的对象不需要这个,但是对切片的字面量“ ...”支持确实需要。


22
它也可用于PEP484类型提示在存根文件
noɥʇʎԀʎzɐɹƆ

24
以防万一有人好奇:它也用在标准库typing模块中:例如Callable[..., int],指示可调用的可返回值int而未指定签名的可调用对象,或Tuple[str, ...]指示可变长度的齐次字符串。
Anakhand

6
仅供参考,FastAPI框架(适用于python 3.6+)也(现在)使用它。fastapi.tiangolo.com/tutorial/query-params-str-validations
Andrew Allaire

2
@ArtOfWarfare您完全正确,这是来自一个有人口头说“省略号”而不是在句子之间拖尾的人。
PrimeRibeyeDeal

我找到了这个。这似乎显示,当你做一个自我引用(循环引用)的列表:a = [1, 2]; a[0] = a; print(a)[[...], 2]。这是同一件事还是不同用途?
比尔

219

在Python 3中,您可以将Ellipsis文字...用作代码的“ nop”占位符:

def will_do_something():
    ...

不是魔术。可以使用任何表达式代替...,例如:

def will_do_something():
    1

(不能使用“批准”一词,但我可以说Guido 并未完全拒绝这种使用。)


180
在一个半会议中,我经常看到...人们习惯于在以后指出他们打算填写的内容(“待办事项”空块),pass意思是一个没有代码的块。
Gareth Latty

26
Python还具有NotImplemented文字,当您希望不完整的函数返回有意义的内容时(而不是None示例中),该文字非常有用。(另一个用例:实现算术运算
zvyn15年

13
@zvyn这不是文字。这只是一个名字。例如NotImplemented = 'something_else'有效的python,但... = 'something_else'语法错误。
wim 2016年

4
@zvyn如果导入该模块时发生异常怎么办?:)
pizzapants184年

7
@zvyn NotImplemented不旨在是可替换的None。它的用法相当狭窄。在此处
汉斯,

68

从Python 3.5和PEP484开始,使用键入模块时,文字省略号用于表示静态类型检查器的某些类型。

范例1:

任意长度的均值元组可以使用一种类型和省略号表示,例如 Tuple[int, ...]

范例2:

通过用文字省略号(三个点)代替参数列表,可以在不指定调用签名的情况下声明可调用对象的返回类型:

def partial(func: Callable[..., str], *args) -> Callable[..., str]:
    # Body

46

在指定预期的doctest输出时,也可以使用省略号:

class MyClass(object):
    """Example of a doctest Ellipsis

    >>> thing = MyClass()
    >>> # Match <class '__main__.MyClass'> and <class '%(module).MyClass'>
    >>> type(thing)           # doctest:+ELLIPSIS
    <class '....MyClass'>
    """
    pass

9
但这实际上是否涉及Ellipsis对象?这不仅仅是doctest解析器/匹配器的功能吗?
akaihola

1
如doctest.ELLIPSIS所述,@ akaihola可以说是的。我希望大多数(即使不是全部)用法...都是语法的,而不是use实际的Ellipsis对象。难道它仅仅是适应性概念的方便名称吗?
nealmcb


25

总结其他人所说的内容,从Python 3开始,Ellipsis本质上是与相似的另一个单例常量None,但没有特定的预期用途。现有用途包括:

  • 以切片语法表示剩余维度中的完整切片
  • 在类型提示中仅指示类型(Callable[..., int]Tuple[str, ...])的一部分
  • 在类型存根文件中以指示存在默认值而不指定它

可能的用途包括:

  • 作为None有效选项的地方的默认值
  • 作为尚未实现的功能的内容

14

__getitem__...自定义类中的最小示例

在自定义类中...传递魔术语法时[],将__getitem__()接收一个Ellipsis类对象。

然后,该类可以使用此Singleton对象执行任何所需的操作。

例:

class C(object):
    def __getitem__(self, k):
        return k

# Single argument is passed directly.
assert C()[0] == 0

# Multiple indices generate a tuple.
assert C()[0, 1] == (0, 1)

# Slice notation generates a slice object.
assert C()[1:2:3] == slice(1, 2, 3)

# Ellipsis notation generates the Ellipsis class object.
# Ellipsis is a singleton, so we can compare with `is`.
assert C()[...] is Ellipsis

# Everything mixed up.
assert C()[1, 2:3:4, ..., 6] == (1, slice(2,3,4), Ellipsis, 6)

Python内置list类选择给它提供范围的语义,当然,对它的任何合理使用也应如此。

就个人而言,我只是在我的API中远离它,而是创建一个单独的,更明确的方法。

已在Python 3.5.2和2.7.12中测试。


使用-O参数运行此代码,您的代码将始终运行; D
moshevi



2

它的预期用途不仅应用于这些第三方模块。在Python文档中没有适当提及(或者也许我找不到),但是CPython实际上至少在一个地方使用省略号...

它用于表示Python中的无限数据结构。我在玩列表时遇到了这个符号。

有关更多信息,请参见此问题


8
不同的东西。这个问题询问ellipsis内置类型和Ellipsis对象。用椭圆表示无限数据结构纯粹是为了显示,与ellipsis类型或Ellipsis对象无关。
chys 2014年

3
@chys实际上,它的作用很小-Python __repr__字符串旨在成为有效的Python表达式-如果它不是用于语言中存在的省略号的话,则表示形式将不是有效的表达式。
Gareth Latty

3
@Lattyware好吧,这确实是原始设计的目的。它还eval(repr(a))旨在等于a。不幸的是,在实践中有时甚至是错误的,即使对于内置类型也是如此。试试看:a=[]; a.append(a); eval(repr(a))repr(a)[[...]]Python 2中的无效表达式。(在Python 3中是有效的,但是评估结果有所不同,仍然与最初的意图背道而驰。)
chys

1

这是等效的。

l=[..., 1,2,3]
l=[Ellipsis, 1,2,3]

...是在内部定义的常量built-in constants

省略

与省略号“ ...”相同。特殊值,通常与用户定义的容器数据类型的扩展切片语法结合使用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.