Ellipsis – це вбудований об’єкт у Python, який позначається символом трьох крапок ... . Він є унікальним (singleton): у програмі існує лише один екземпляр цього об’єкта. Тип Ellipsis – це окремий клас ellipsis, і він належить до спеціальних об’єктів мови поряд із None, True та False:

print(type(...))  # <class 'ellipsis'>
print(... is Ellipsis)  # True

Використання Ellipsis

У Python є кілька основних способів застосування об’єкта Ellipsis:

1. Заглушки функцій та методів

Ellipsis часто використовується для створення функцій-заглушок (stubs). Він дозволяє явно позначити, що реалізація методу чи функції ще не готова:

def some_function():
    ...  # Реалізація буде додана пізніше

На відміну від оператора pass, який просто означає «нічого не робити», три крапки ... виглядають більш виразно й одразу сигналізують про незавершеність коду:

def some_function():
    pass  # менш помітний варіант

2. У Type Hints

Починаючи з Python 3.5, Ellipsis використовується у анотаціях типів, зокрема для позначення довільної кількості елементів у колекціях. Поширений приклад – кортежі змінної довжини:

from typing import Tuple


def process_tuple(data: Tuple[int, ...]) -> None:
    print(data)


process_tuple((1, 2, 3, 4))  # коректно
process_tuple((1,))  # також коректно

Запис Tuple[int, ...] означає «кортеж будь-якої довжини, що складається з цілих чисел». У цьому контексті ... є частиною синтаксису для type hints і не має відношення до заглушок.

3. Значення аргументу за замовчуванням

Ellipsis можна використовувати як унікальний маркер у параметрах функцій. Це дозволяє відрізнити випадки, коли аргумент:

  • взагалі не був переданий
  • був явно переданий як None
  • або отримав інше значення
def process(value=...):
    if value is ...:
        print('Значення не передано')
    elif value is None:
        print('Значення явно задане як None')
    else:
        print(f'Значення: {value}')


process()  # Значення не передано
process(None)  # Значення явно задане як None
process(42)  # Значення: 42

Цей підхід зручний у тих випадках, коли None є валідним аргументом і не може слугувати «ознакою відсутності значення».

4. Зрізи багатовимірних масивів

Ellipsis є зручним інструментом для роботи з багатовимірними масивами, зокрема в бібліотеці NumPy. Він дозволяє компактно записувати зрізи, коли потрібно вибрати всі елементи вздовж кількох осей:

import numpy as np

# Створення 3D-масиву (shape: 3 x 3 x 3)
array = np.arange(27).reshape(3, 3, 3)

# Вибір усіх елементів по перших двох вимірах і лише 0-го індексу по останньому
result = array[..., 0]

print('array:')
print(array)
print()
print('result:')
print(result)

Результат:

array:
[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]]

 [[ 9 10 11]
  [12 13 14]
  [15 16 17]]

 [[18 19 20]
  [21 22 23]
  [24 25 26]]]

result:
[[ 0  3  6]
 [ 9 12 15]
 [18 21 24]]

Вираз array[..., 0] означає: «візьми всі елементи по всіх вимірах, крім останнього, і вибери 0-й індекс у останньому вимірі». Такий запис особливо корисний для високорозмірних масивів, оскільки робить код більш лаконічним і читабельним.

pass vs …

Хоча pass та Ellipsis іноді можуть виглядати подібно (наприклад, як «порожній» код), насправді вони мають різну природу й призначення:

  • pass – це оператор. Він використовується для заповнення блоків коду, де синтаксично потрібно щось написати, але виконувати дію не потрібно.
  • ... – це об’єкт типу ellipsis. Його головні сфери застосування – анотації типів, зрізи багатовимірних масивів NumPy, а також роль спеціального маркера або заглушки.
# Використання pass
def todo_function():
    pass  # нічого не робить, але синтаксично правильно

# Використання Ellipsis
def stub_function():
    ...  # заглушка, яка сигналізує: код ще не реалізований

print(type(...))  # <class 'ellipsis'>

Таким чином, pass – це інструкція для інтерпретатора, а Ellipsis – повноцінний об’єкт. Вони можуть доповнювати одне одного, але не є взаємозамінними у більшості випадків.


Мітки: