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 применяется для буферов, журналов последних событий и очередей с фиксированной ёмкостью; при переполнении он не создаёт исключение, а незаметно вытесняет старые данные.
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
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__ либо выбрать другой способ хранения кэша.
2. Декоратор cached_property заменяет метод total дескриптором, который должен один раз вычислить результат и записать его в __dict__ экземпляра.
3. Конструктор успешно сохраняет переданный список в предусмотренный слот lines.
4. При чтении total дескриптор сначала пытается получить __dict__ объекта для будущей записи кэшированного значения. До вызова функции с sum дело не доходит.
5. Поскольку у экземпляра нет __dict__, cached_property возбуждает TypeError. Аргумент print не вычислен, поэтому в стандартный вывод ничего не попадает.
Почему это важно
Задача относится к взаимодействию дескрипторов и модели хранения атрибутов. В проектах __slots__ применяют для сокращения памяти, а cached_property — для ленивых вычислений. Их прямое сочетание требует добавить __dict__ в __slots__ либо выбрать другой способ хранения кэша.
✍1
Python: задачки и вопросы
Развёрнутое пояснение:
1. Создаётся функция load_rate, которая при вызове печатает строку «резерв» и возвращает 99.
2. В словарь rates записывается существующий тариф standard со значением 10.
3. Перед вызовом rates.get Python вычисляет все переданные аргументы, включая выражение load_rate().
4. load_rate печатает «резерв» и возвращает 99, которое становится запасным значением для get.
5. Метод get находит ключ standard, поэтому возвращает 10, а уже вычисленное запасное значение 99 не использует.
6. Последний print выводит 10, поэтому итоговый вывод состоит из строк «резерв» и «10».
Почему это важно
Задача проверяет порядок вычисления аргументов функции. В реальном проекте передача затратной загрузки или запроса к резервному сервису прямо в dict.get может выполнять лишнюю работу даже при наличии ключа. Для ленивого получения запасного значения сначала проверяют наличие ключа или используют другую явную ветвь выполнения.
2. В словарь rates записывается существующий тариф standard со значением 10.
3. Перед вызовом rates.get Python вычисляет все переданные аргументы, включая выражение load_rate().
4. load_rate печатает «резерв» и возвращает 99, которое становится запасным значением для get.
5. Метод get находит ключ standard, поэтому возвращает 10, а уже вычисленное запасное значение 99 не использует.
6. Последний print выводит 10, поэтому итоговый вывод состоит из строк «резерв» и «10».
Почему это важно
Задача проверяет порядок вычисления аргументов функции. В реальном проекте передача затратной загрузки или запроса к резервному сервису прямо в dict.get может выполнять лишнюю работу даже при наличии ключа. Для ленивого получения запасного значения сначала проверяют наличие ключа или используют другую явную ветвь выполнения.
✍2
Python: задачки и вопросы
Развёрнутое пояснение:
1. defaults содержит исходные значения timeout и retries, а env изначально пуст.
2. ChainMap объединяет отображения для чтения, причём env имеет приоритет перед defaults.
3. Присваивание через config не ищет отображение, где ключ уже существует: значение retries записывается в первое отображение env.
4. Удаление через ChainMap также применяется только к первому отображению. Ключа timeout в env нет, поэтому возникает KeyError, хотя он доступен для чтения из defaults.
5. Обработчик перехватывает KeyError и печатает env с добавленным retries и неизменённый defaults, поэтому вывод равен {'retries': 5} {'timeout': 30, 'retries': 2}.
Почему это важно: задача проверяет модель записи и удаления в ChainMap. В многослойных конфигурациях чтение проходит по всем слоям, но изменения не переносятся автоматически в слой, где найдено исходное значение.
2. ChainMap объединяет отображения для чтения, причём env имеет приоритет перед defaults.
3. Присваивание через config не ищет отображение, где ключ уже существует: значение retries записывается в первое отображение env.
4. Удаление через ChainMap также применяется только к первому отображению. Ключа timeout в env нет, поэтому возникает KeyError, хотя он доступен для чтения из defaults.
5. Обработчик перехватывает KeyError и печатает env с добавленным retries и неизменённый defaults, поэтому вывод равен {'retries': 5} {'timeout': 30, 'retries': 2}.
Почему это важно: задача проверяет модель записи и удаления в ChainMap. В многослойных конфигурациях чтение проходит по всем слоям, но изменения не переносятся автоматически в слой, где найдено исходное значение.
✍1
Python: задачки и вопросы
Развёрнутое пояснение:
1. Кортеж regions задаёт два ключа: eu и us.
2. dict.fromkeys(regions, []) создаёт словарь, в котором оба ключа ссылаются на один и тот же пустой список.
3. append изменяет этот общий список, поэтому order-7 становится виден через оба ключа.
4. Выражение queues["us"] + ["order-8"] создаёт новый список, не изменяя исходный.
5. Присваивание связывает ключ us с новым списком, а eu сохраняет ссылку на прежний; поэтому вывод содержит order-7 у eu и оба заказа у us.
Почему это важно
Задача проверяет понимание общего изменяемого состояния и различия между изменением объекта и заменой ссылки. Такое поведение встречается при создании словарей очередей, групп и накопителей через dict.fromkeys.
2. dict.fromkeys(regions, []) создаёт словарь, в котором оба ключа ссылаются на один и тот же пустой список.
3. append изменяет этот общий список, поэтому order-7 становится виден через оба ключа.
4. Выражение queues["us"] + ["order-8"] создаёт новый список, не изменяя исходный.
5. Присваивание связывает ключ us с новым списком, а eu сохраняет ссылку на прежний; поэтому вывод содержит order-7 у eu и оба заказа у us.
Почему это важно
Задача проверяет понимание общего изменяемого состояния и различия между изменением объекта и заменой ссылки. Такое поведение встречается при создании словарей очередей, групп и накопителей через dict.fromkeys.
✍1
Python: задачки и вопросы
Развёрнутое пояснение:
1. Вызов orders() создаёт объект генератора, но его тело пока не выполняется.
2. next(stream) запускает генератор: печатается open, затем выполнение доходит до yield 101 и приостанавливается.
3. Внешний print получает значение 101 и печатает его.
4. Следующий print выводит done, поскольку генератор всё ещё приостановлен на yield.
5. stream.close() передаёт в точку приостановки служебное исключение GeneratorExit. Обычное продолжение после yield не происходит, поэтому строка next не печатается.
6. Перед завершением генератор обязательно выполняет блок finally, который печатает close. Итоговый порядок строк: open, 101, done, close.
Почему это важно
Задача проверяет жизненный цикл генераторов и гарантированную очистку ресурсов. В потоковой обработке генератор может удерживать файл, соединение или транзакцию; если потребитель прекращает чтение досрочно, явный вызов close() запускает очистку из finally, но не продолжает обычную обработку оставшихся элементов.
2. next(stream) запускает генератор: печатается open, затем выполнение доходит до yield 101 и приостанавливается.
3. Внешний print получает значение 101 и печатает его.
4. Следующий print выводит done, поскольку генератор всё ещё приостановлен на yield.
5. stream.close() передаёт в точку приостановки служебное исключение GeneratorExit. Обычное продолжение после yield не происходит, поэтому строка next не печатается.
6. Перед завершением генератор обязательно выполняет блок finally, который печатает close. Итоговый порядок строк: open, 101, done, close.
Почему это важно
Задача проверяет жизненный цикл генераторов и гарантированную очистку ресурсов. В потоковой обработке генератор может удерживать файл, соединение или транзакцию; если потребитель прекращает чтение досрочно, явный вызов close() запускает очистку из finally, но не продолжает обычную обработку оставшихся элементов.