> **Источник:** https://python-all.ru/3.12/library/selectors.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# `selectors` – высокоуровневое мультиплексирование ввода-вывода

Добавлено в версии 3.4.

**Исходный код:** [Lib/selectors.py](https://python-all.ru/src/3.12/Lib/selectors.py)

---

## Введение

Этот модуль обеспечивает высокоуровневое и эффективное мультиплексирование ввода-вывода, построенное на основе примитивов модуля [`select`](https://python-all.ru/3.12/library/select.html#module-select). Пользователям рекомендуется использовать этот модуль вместо него, если только не требуется точный контроль над используемыми примитивами уровня ОС.

Он определяет абстрактный базовый класс [`BaseSelector`](https://python-all.ru/3.12/library/selectors.html#selectors.BaseSelector) вместе с несколькими конкретными реализациями ([`KqueueSelector`](https://python-all.ru/3.12/library/selectors.html#selectors.KqueueSelector), [`EpollSelector`](https://python-all.ru/3.12/library/selectors.html#selectors.EpollSelector)…), которые можно использовать для ожидания уведомлений о готовности ввода-вывода для нескольких файловых объектов. В дальнейшем под «файловым объектом» понимается любой объект с методом [`fileno()`](https://python-all.ru/3.12/library/io.html#io.IOBase.fileno) или файловый дескриптор. См. [файловый объект](https://python-all.ru/3.12/glossary.html#term-file-object).

[`DefaultSelector`](https://python-all.ru/3.12/library/selectors.html#selectors.DefaultSelector) – это псевдоним для наиболее эффективной реализации, доступной на текущей платформе; для большинства пользователей его следует выбирать по умолчанию.

> **Примечание**
>
> Тип поддерживаемых файловых объектов зависит от платформы: в Windows поддерживаются сокеты, но не каналы, тогда как в Unix поддерживаются и сокеты, и каналы (также могут поддерживаться и другие типы, например именованные каналы или специальные файловые устройства).

> **См. также**
>
> **[`select`](https://python-all.ru/3.12/library/select.html#module-select)**
>
> Модуль низкоуровневого мультиплексирования ввода-вывода.

[Доступность](https://python-all.ru/3.12/library/intro.html#availability): not Emscripten, not WASI.

Этот модуль не работает или недоступен на платформах WebAssembly `wasm32-emscripten` и `wasm32-wasi`. См. [платформы WebAssembly](https://python-all.ru/3.12/library/intro.html#wasm-availability) для получения дополнительной информации.

## Классы

Иерархия классов:

```python
BaseSelector
+-- SelectSelector
+-- PollSelector
+-- EpollSelector
+-- DevpollSelector
+-- KqueueSelector
```

В следующих описаниях *events* – это битовая маска, указывающая, какие события ввода-вывода должны ожидаться для заданного файлового объекта. Она может быть комбинацией констант модуля, приведённых ниже:

> | Константа | Значение |
> | --- | --- |
> | selectors.EVENT\_READ | Доступен для чтения |
> | selectors.EVENT\_WRITE | Доступен для записи |

#### `class selectors.SelectorKey`

Объект [`SelectorKey`](https://python-all.ru/3.12/library/selectors.html#selectors.SelectorKey) – это [`namedtuple`](https://python-all.ru/3.12/library/collections.html#collections.namedtuple), используемый для связывания файлового объекта с его нижележащим файловым дескриптором, выбранной маской событий и присоединенными данными. Он возвращается несколькими методами [`BaseSelector`](https://python-all.ru/3.12/library/selectors.html#selectors.BaseSelector).

#### `fileobj`

Зарегистрированный файловый объект.

#### `fd`

Нижележащий файловый дескриптор.

#### `events`

События, которые необходимо ожидать для этого файлового объекта.

#### `data`

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

#### `class selectors.BaseSelector`

Объект [`BaseSelector`](https://python-all.ru/3.12/library/selectors.html#selectors.BaseSelector) используется для ожидания готовности событий ввода-вывода на нескольких файловых объектах. Он поддерживает регистрацию и отмену регистрации файловых потоков, а также метод для ожидания событий ввода-вывода на этих потоках с необязательным тайм-аутом. Это абстрактный базовый класс, поэтому его нельзя инстанцировать. Используйте [`DefaultSelector`](https://python-all.ru/3.12/library/selectors.html#selectors.DefaultSelector) вместо него или один из [`SelectSelector`](https://python-all.ru/3.12/library/selectors.html#selectors.SelectSelector), [`KqueueSelector`](https://python-all.ru/3.12/library/selectors.html#selectors.KqueueSelector) и т.д., если нужна конкретная реализация и ваша платформа её поддерживает. [`BaseSelector`](https://python-all.ru/3.12/library/selectors.html#selectors.BaseSelector) и его конкретные реализации поддерживают протокол [менеджера контекста](https://python-all.ru/3.12/glossary.html#term-context-manager).

#### `abstractmethod register(fileobj, events, data=None)`

Регистрирует файловый объект для выбора, отслеживая события ввода-вывода.

*fileobj* – файловый объект для мониторинга. Он может быть целочисленным файловым дескриптором или объектом с методом `fileno()`. *events* – побитовая маска событий для мониторинга. *data* – непрозрачный объект.

Это возвращает новый экземпляр [`SelectorKey`](https://python-all.ru/3.12/library/selectors.html#selectors.SelectorKey) или возбуждает [`ValueError`](https://python-all.ru/3.12/library/exceptions.html#ValueError) в случае недопустимой маски событий или файлового дескриптора, или [`KeyError`](https://python-all.ru/3.12/library/exceptions.html#KeyError), если файловый объект уже зарегистрирован.

#### `abstractmethod unregister(fileobj)`

Отменяет регистрацию файлового объекта, удаляя его из отслеживания. Файловый объект должен быть отменён до закрытия.

*fileobj* должен быть ранее зарегистрированным файловым объектом.

Возвращает экземпляр [`SelectorKey`](https://python-all.ru/3.12/library/selectors.html#selectors.SelectorKey) или возбуждает [`KeyError`](https://python-all.ru/3.12/library/exceptions.html#KeyError), если *fileobj* не зарегистрирован. Возбуждает [`ValueError`](https://python-all.ru/3.12/library/exceptions.html#ValueError), если *fileobj* некорректен (например, у него нет метода `fileno()` или его метод `fileno()` возвращает недопустимое значение).

#### `modify(fileobj, events, data=None)`

Изменяет отслеживаемые события или присоединённые данные зарегистрированного файлового объекта.

Это эквивалентно последовательному вызову `BaseSelector.unregister(fileobj)` и `BaseSelector.register(fileobj, events, data)`, за исключением того, что может быть реализовано более эффективно.

Возвращает новый экземпляр [`SelectorKey`](https://python-all.ru/3.12/library/selectors.html#selectors.SelectorKey) или возбуждает [`ValueError`](https://python-all.ru/3.12/library/exceptions.html#ValueError) в случае недопустимой маски событий или файлового дескриптора, или [`KeyError`](https://python-all.ru/3.12/library/exceptions.html#KeyError), если файловый объект не зарегистрирован.

#### `abstractmethod select(timeout=None)`

Ожидает, пока некоторые зарегистрированные файловые объекты не станут готовы, или пока не истечёт тайм-аут.

Если `timeout > 0`, задаёт максимальное время ожидания в секундах. Если `timeout <= 0`, вызов не будет блокироваться и сообщит о текущих готовых файловых объектах. Если *timeout* равен `None`, вызов будет блокироваться до тех пор, пока отслеживаемый файловый объект не станет готовым.

Возвращает список кортежей `(key, events)`, по одному для каждого готового файлового объекта.

*key* – это экземпляр [`SelectorKey`](https://python-all.ru/3.12/library/selectors.html#selectors.SelectorKey), соответствующий готовому файловому объекту. *events* – битовая маска событий, готовых на этом файловом объекте.

> **Примечание**
>
> Этот метод может вернуть результат до того, как какой-либо файловый объект станет готовым или истечёт тайм-аут, если текущий процесс получает сигнал: в этом случае будет возвращён пустой список.

Изменено в версии 3.5: Теперь при прерывании сигналом селектор повторяет попытку с пересчитанным тайм-аутом, если обработчик сигнала не возбудил исключение (см. [**PEP 475**](https://python-all.ru/3.12/library/selectors.html) для обоснования), вместо того чтобы возвращать пустой список событий до истечения тайм-аута.

#### `close()`

Закрывает селектор.

Должен быть вызван, чтобы гарантировать освобождение всех базовых ресурсов. Селектор нельзя использовать после его закрытия.

#### `get_key(fileobj)`

Возвращает ключ, связанный с зарегистрированным файловым объектом.

Возвращает экземпляр [`SelectorKey`](https://python-all.ru/3.12/library/selectors.html#selectors.SelectorKey), связанный с этим файловым объектом, или возбуждает [`KeyError`](https://python-all.ru/3.12/library/exceptions.html#KeyError), если файловый объект не зарегистрирован.

#### `abstractmethod get_map()`

Возвращает отображение файловых объектов на ключи селектора.

Возвращает экземпляр [`Mapping`](https://python-all.ru/3.12/library/collections.abc.html#collections.abc.Mapping), отображающий зарегистрированные файловые объекты на соответствующие экземпляры [`SelectorKey`](https://python-all.ru/3.12/library/selectors.html#selectors.SelectorKey).

#### `class selectors.DefaultSelector`

Класс селектора по умолчанию, использующий наиболее эффективную реализацию, доступную на текущей платформе. Должен быть выбором по умолчанию для большинства пользователей.

#### `class selectors.SelectSelector`

селектор на основе [`select.select()`](https://python-all.ru/3.12/library/select.html#select.select).

#### `class selectors.PollSelector`

селектор на основе [`select.poll()`](https://python-all.ru/3.12/library/select.html#select.poll).

#### `class selectors.EpollSelector`

селектор на основе [`select.epoll()`](https://python-all.ru/3.12/library/select.html#select.epoll).

#### `fileno()`

Возвращает файловый дескриптор, используемый базовым объектом [`select.epoll()`](https://python-all.ru/3.12/library/select.html#select.epoll).

#### `class selectors.DevpollSelector`

селектор на основе [`select.devpoll()`](https://python-all.ru/3.12/library/select.html#select.devpoll).

#### `fileno()`

Возвращает файловый дескриптор, используемый базовым объектом [`select.devpoll()`](https://python-all.ru/3.12/library/select.html#select.devpoll).

Добавлено в версии 3.5.

#### `class selectors.KqueueSelector`

селектор на основе [`select.kqueue()`](https://python-all.ru/3.12/library/select.html#select.kqueue).

#### `fileno()`

Возвращает файловый дескриптор, используемый базовым объектом [`select.kqueue()`](https://python-all.ru/3.12/library/select.html#select.kqueue).

## Примеры

Ниже приведена простая реализация эхо-сервера:

```python
import selectors
import socket

sel = selectors.DefaultSelector()

def accept(sock, mask):
    conn, addr = sock.accept()  # Должен быть готов
    print('accepted', conn, 'from', addr)
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read)

def read(conn, mask):
    data = conn.recv(1000)  # Должен быть готов
    if data:
        print('echoing', repr(data), 'to', conn)
        conn.send(data)  # Надеюсь, не заблокируется
    else:
        print('closing', conn)
        sel.unregister(conn)
        conn.close()

sock = socket.socket()
sock.bind(('localhost', 1234))
sock.listen(100)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)

while True:
    events = sel.select()
    for key, mask in events:
        callback = key.data
        callback(key.fileobj, mask)
```
