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 – повноцінний об’єкт. Вони можуть доповнювати одне одного, але не є взаємозамінними у більшості випадків.