Python: задачки и вопросы
6.93K subscribers
1.35K photos
1 video
1 file
127 links
Вопросы и задачки для подготовки к собеседованиям и прокачки навыков

Разместить рекламу: @tproger_sales_bot

Правила общения: https://tprg.ru/rules

Другие каналы: @tproger_channels

Другие наши проекты: https://tprg.ru/media
Download Telegram
Python: задачки и вопросы
Развёрнутое пояснение:

1. При входе в блок with вызывается метод __enter__, который печатает begin.

2. Тело блока печатает write, после чего возбуждает исключение ValueError.

3. Перед выходом из блока Python вызывает __exit__ и передаёт ему тип, значение и трассировку исключения.

4. __exit__ печатает имя типа исключения — ValueError — и возвращает True.

5. Истинное возвращаемое значение сообщает Python, что исключение обработано, поэтому строка после блока выполняется и печатает continued. Итоговый вывод: begin, write, ValueError и continued на отдельных строках.

Почему это важно

Задача проверяет протокол менеджеров контекста. На практике __exit__ часто освобождает соединения, завершает транзакции и управляет распространением ошибок; случайное возвращение истинного значения может скрыть сбой и позволить программе продолжить работу с некорректным состоянием.
✍1
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Python: задачки и вопросы
Развёрнутое пояснение:

1. asyncio.run запускает цикл событий и начинает выполнять main.

2. Первый вызов create_task планирует задачу db, но send ещё не начинает исполняться, поскольку main пока не передал управление циклу событий.

3. Второй вызов create_task аналогично планирует задачу log.

4. На await db функция main приостанавливается, и цикл событий запускает запланированные задачи в порядке их постановки.

5. Задача db печатает send db и приостанавливается на asyncio.sleep(0).

6. Затем задача log печатает send log и тоже приостанавливается.

7. После завершения db ожидание в main заканчивается, и main печатает saved. Поэтому строки выводятся в порядке send db, send log, saved.

Почему это важно: create_task запускает конкурентную задачу при ближайшей передаче управления циклу событий. Ожидание одной задачи не мешает другим уже запланированным задачам начать работу, что важно учитывать при отправке данных, обновлении метрик и обработке очередей.
✍4
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Python: задачки и вопросы
Развёрнутое пояснение:

1. Для класса Client строится порядок разрешения методов: Client, Audit, Retry, Base, object.

2. Вызов send сначала находит реализацию в Audit, которая создаёт список с элементом audit.

3. super() внутри Audit продолжает поиск после Audit, поэтому вызывает Retry.send, а не Base.send напрямую.

4. Retry добавляет retry и через свой super() передаёт управление методу Base.send.

5. Base.send возвращает список с base; результаты последовательно объединяются, поэтому вывод равен ['audit', 'retry', 'base'].

Почему это важно: задача проверяет кооперативное наследование и порядок разрешения методов. Такой подход применяется в примесях для журналирования, повторных попыток и проверки доступа; каждый класс должен передавать управление через super(), чтобы вся цепочка выполнилась.
✍2
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Python: задачки и вопросы
Развёрнутое пояснение:

1. Создаётся контекстная переменная request_id без значения по умолчанию.

2. В задаче main переменной request_id присваивается значение A.

3. asyncio.create_task создаёт задачу audit и копирует в неё текущий контекст, где request_id равен A.

4. Затем main меняет request_id на B только в собственном контексте.

5. Когда запускается audit, она читает свою копию контекста и печатает A.

Почему это важно

ContextVar применяется для хранения идентификаторов запросов, данных трассировки и другого состояния асинхронной операции. Контекст задачи фиксируется при её создании, поэтому изменение переменной перед фактическим запуском задачи не обновляет уже скопированный контекст.
✍1
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Python: задачки и вопросы
Развёрнутое пояснение:

1. defaultdict(int) создаёт словарь, в котором фабрика int возвращает 0 для отсутствующего ключа.

2. Выражение errors['api'] += 1 сначала получает значение 0, увеличивает его и сохраняет 1 для ключа 'api'.

3. Обращение errors['db'] не вызывает KeyError: defaultdict вызывает int без аргументов, получает 0 и добавляет пару 'db': 0.

4. Первый print выводит 0, а второй — обычное представление словаря с ключами в порядке их добавления: {'api': 1, 'db': 0}.

Почему это важно

Задача относится к поведению defaultdict при чтении отсутствующих ключей. В счётчиках метрик простая проверка значения может незаметно изменить словарь, создать лишние записи и повлиять на последующую сериализацию или обход данных.
✍1
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Python: задачки и вопросы
Развёрнутое пояснение:

1. deque создаёт очередь из a и b с максимальной длиной 3.

2. append добавляет c справа, и очередь становится [a, b, c].

3. Добавление d превышает maxlen, поэтому deque автоматически удаляет a слева и сохраняет [b, c, d].

4. popleft извлекает b, после чего в очереди остаются c и d.

5. print выводит извлечённое значение b и список ['c', 'd'], поэтому получается b ['c', 'd'].

Почему это важно: ограниченный deque применяется для буферов, журналов последних событий и очередей с фиксированной ёмкостью; при переполнении он не создаёт исключение, а незаметно вытесняет старые данные.
✍1
Please open Telegram to view this post
VIEW IN TELEGRAM
✍1
Python: задачки и вопросы
Развёрнутое пояснение:

1. При создании класса __slots__ разрешает экземплярам хранить атрибут lines, но не создаёт для них словарь __dict__.

2. Декоратор cached_property заменяет метод total дескриптором, который должен один раз вычислить результат и записать его в __dict__ экземпляра.

3. Конструктор успешно сохраняет переданный список в предусмотренный слот lines.

4. При чтении total дескриптор сначала пытается получить __dict__ объекта для будущей записи кэшированного значения. До вызова функции с sum дело не доходит.

5. Поскольку у экземпляра нет __dict__, cached_property возбуждает TypeError. Аргумент print не вычислен, поэтому в стандартный вывод ничего не попадает.

Почему это важно

Задача относится к взаимодействию дескрипторов и модели хранения атрибутов. В проектах __slots__ применяют для сокращения памяти, а cached_property — для ленивых вычислений. Их прямое сочетание требует добавить __dict__ в __slots__ либо выбрать другой способ хранения кэша.
✍1