Что делает объект Python Ellipsis? - PullRequest
411 голосов
/ 21 апреля 2009

Во время лёгкой навигации по пространству имен я заметил странно выглядящий объект с именем " Ellipsis ", он, кажется, не делает или делает что-то особенное, но это глобально доступный встроенный объект.

После поиска я обнаружил, что он используется в каком-то непонятном варианте синтаксиса срезов Нампи и Сципи ... но почти ничего больше.

Был ли этот объект добавлен в язык специально для поддержки 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

Ответы [ 11 ]

449 голосов
/ 21 апреля 2009

Это недавно появилось в другом вопросе . Я уточню мой ответ оттуда:

Многоточие - это объект, который может отображаться в обозначениях срезов. Например:

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

Его интерпретация полностью зависит от того, что реализует функцию __getitem__ и видит там Ellipsis объекты, но ее основное (и предполагаемое) использование - расширение числовой python , которое добавляет многомерный массив тип. Поскольку существует более одного измерения, нарезка становится более сложной, чем просто индекс начала и остановки; полезно также иметь возможность разрезать по нескольким измерениям. Например, для массива 4x4 верхняя левая область будет определяться срезом [: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]])

Расширяя это далее, Ellipsis используется здесь, чтобы указать местозаполнитель для остальных измерений массива, не указанных. Думайте об этом как об указании полного среза [:] для всех размеров в зазоре, который он помещает, поэтому для трехмерного массива a[...,0] совпадает с a[:,:,0] и для 4d, a[:,:,:,0], аналогично a[0,...,0] равно a[0,:,:,0] (хотя большое количество двоеточий в середине составляет полное число измерений в массиве).

Интересно, что в python3 литерал Ellipsis (...) можно использовать вне синтаксиса слайса, поэтому вы можете написать:

>>> ...
Ellipsis

За исключением различных числовых типов, нет, я не думаю, что он используется. Насколько я знаю, он был добавлен исключительно для простого использования и не поддерживает ядро, кроме предоставления объекта и соответствующего синтаксиса. Объект, находящийся там, не требовал этого, но буквальная «...» поддержка срезов сделала.

158 голосов
/ 31 мая 2011

В Python 3 вы можете использовать литерал Ellipsis ... в качестве заполнителя «nop» для кода:

def will_do_something():
    ...

Это не магия; вместо ... можно использовать любое выражение, например ::100100

def will_do_something():
    1

(Не могу использовать слово «санкционировано», но я могу сказать, что это использование было , не отвергнутое напрямую Гвидо.)

41 голосов
/ 28 мая 2016

Начиная с Python 3.5 и PEP484 , буквенный многоточие используется для обозначения определенных типов для средства проверки статического типа при использовании модуля typing .

Пример 1:

Однородные кортежи произвольной длины могут быть выражены с использованием одного типа и многоточия, например Tuple[int, ...]

Пример 2:

Можно объявить тип возвращаемого значения вызываемого объекта без указания сигнатуры вызова, подставив в качестве аргумента буквенный многоточие (три точки):

def partial(func: Callable[..., str], *args) -> Callable[..., str]:
    # Body
41 голосов
/ 31 мая 2011

Вы также можете использовать многоточие при указании ожидаемого doctest output:

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
31 голосов
/ 21 апреля 2009

Из документации Python :

Этот объект используется расширенным срезом обозначения (см. Python Reference Руководство ). Не поддерживает никаких специальных операции. Есть ровно один объект эллипса с именем Ellipsis ( встроенное имя).

15 голосов
/ 03 июня 2018

Подводя итог тому, что говорили другие, начиная с Python 3, Ellipsis, по сути, является еще одной одноэлементной константой, похожей на None, но без конкретного предполагаемого использования. Существующее использование включает:

  • В синтаксисе среза для представления полного среза в оставшихся измерениях
  • В подсказке типа указывается только часть типа (Callable[..., int] или Tuple[str, ...])
  • В файлах заглушки типа, чтобы указать, что есть значение по умолчанию, не указывая его

Возможные варианты использования:

  • В качестве значения по умолчанию для мест, где None является допустимым параметром
  • Как контент для функции, которую вы еще не реализовали
11 голосов
/ 21 апреля 2009

Вы можете использовать Ellipsis самостоятельно, в пользовательских ситуациях нарезки, как это делал numpy, но он не используется ни в одном встроенном классе.

Я не знаю, было ли это добавлено специально для использования в numpy, но я, конечно, не видел, чтобы оно использовалось где-либо еще.

См. Также: Как использовать синтаксис нарезки многоточия в Python?

9 голосов

__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.

2 голосов
/ 23 января 2018

Как упомянуто @ noɥʇʎԀʎzɐɹƆ и @phoenix - вы действительно можете использовать его в заглушках. например

class Foo:
    bar: Any = ...
    def __init__(self, name: str=...) -> None: ...

Более подробную информацию и примеры использования этого многоточия можно найти здесь https://www.python.org/dev/peps/pep-0484/#stub-files

2 голосов
/ 20 июля 2013

Предполагаемое использование не должно быть только для этих сторонних модулей. Он не упоминается должным образом в документации по Python (или, может быть, я просто не смог этого найти), но многоточие ... фактически используется в CPython хотя бы в одном месте.

Используется для представления бесконечных структур данных в Python. Я наткнулся на это обозначение, играя со списками.

Подробнее см. . .

...