Python: задачки и вопросы
Kanalga Telegram’da o‘tish
Вопросы и задачки для подготовки к собеседованиям и прокачки навыков Разместить рекламу: @tproger_sales_bot Правила общения: https://tprg.ru/rules Другие каналы: @tproger_channels Другие наши проекты: https://tprg.ru/media
Ko'proq ko'rsatish6 872
Obunachilar
-124 soatlar
-147 kun
-4930 kun
Postlar arxiv
По шагам:
1️⃣ Вызов Application() запускает процесс создания инстанса. Первым делом всегда вызывается метод new, который отрабатывает и печатает new
2️⃣ Вместо стандартного создания объекта через super().__new__(cls) наш метод возвращает экземпляр чужого класса Mock
3️⃣ Под капотом Python строго проверяет тип возвращенного объекта. Если тип совпадает с запрошенным cls, интерпретатор вызывает init
4️⃣ Поскольку мы передали объект класса Mock, Python видит, что инициализировать его через Application.__init__ логически неверно, и просто пропускает этот шаг
5️⃣ В итоге на экран выводится только строка new
Почему это важно
Глубокое понимание скрытых механик языка и архитектурных паттернов отличает уверенного инженера от новичка. Если вы хотите систематизировать эти знания и ускорить карьерный рост, обратите внимание на курс Middle Python от Яндекс Практикума PRO. Программа разработана для специалистов с опытом: там нет базового синтаксиса, весь фокус направлен на хардкорную практику, асинхронную архитектуру и профилирование нагрузки. Это позволяет усилить уже имеющийся опыт и уверенно забирать задачи уровня middle.
Реклама. Рекламодатель: АНО ДПО «Образовательные технологии Яндекса» ИНН 7704282033, erid: 2W5zFJVPBbP
По шагам:
1️⃣Переменная x объявляется в глобальной области видимости и получает значение 1.
2️⃣При вызове функции func интерпретатор встречает команду вывода переменной x.
3️⃣Поскольку внутри функции нет своей локальной переменной с таким именем, Python по правилу разрешения областей видимости (LEGB) поднимается на один уровень выше.
4️⃣В глобальной области находится нужная переменная, и на экран штатно выводится 1.
Почему это важно
Это базовое правило работы с областями видимости. Важно твёрдо помнить, что чтение глобальных переменных работает прозрачно и «из коробки». Иногда новички ищут здесь подвох, ожидая ошибку, но проблемы начинаются только в момент попытки изменить такую переменную.
По шагам:
1️⃣Интерпретатор начинает чтение инструкции по созданию нового класса MyBool.
2️⃣В качестве родительского класса передаётся встроенный тип bool.
3️⃣В исходном коде CPython для структуры класса bool отсутствует специальный флаг Py_TPFLAGS_BASETYPE, который разрешает другим классам расширять его.
4️⃣Создание класса немедленно отклоняется с ошибкой TypeError: type 'bool' is not an acceptable base type.
5️⃣До функции print поток выполнения программы даже не добирается.
Почему это важно
Это редкий пример жёсткого архитектурного ограничения в гибком Python. Понимание того, что базовые концепции истины и лжи аппаратно защищены от переопределения, уберегает от странных идей по созданию собственных логических типов, которые могли бы сломать стандартные проверки if в чужом коде.
Подробное объяснение (по шагам)
1️⃣При создании словаря сначала добавляется пара True: "yes".
2️⃣Затем интерпретатор видит ключ 1. Так как тип bool наследуется от int, для питона True == 1. Их хэши тоже равны. Вместо создания нового ключа, обновляется значение старого: словарь становится {True: "no"}.
3️⃣Затем идёт ключ 1.0. Значение 1.0 == 1 == True. Снова происходит перезапись значения по существующему ключу.
4️⃣Итоговый словарь выглядит так: {True: "maybe"}. Его длина равна 1.
5️⃣При обращении d[True] мы получаем последнее сохранённое значение — "maybe".
Почему это важно
Задачка наглядно демонстрирует устройство хэш-таблиц (словарей и множеств) под капотом. Ключи считаются одинаковыми не по совпадению типов, а если их хэши равны (hash(a) == hash(b)) и сами объекты равны (a == b). Это нужно помнить при смешивании разных числовых типов в ключах.
Подробное объяснение
1️⃣Под капотом Python булевы значения являются обычными числами: True ведёт себя как 1, а False как 0.
2️⃣Первое действие в скобках: (x + y) превращается в (1 + 0), что даёт 1.
3️⃣Затем происходит умножение: 1 * 5 равно 5.
4️⃣Второе действие в скобках: (x == y) проверяет, равно ли True значению False. Это ложь, поэтому возвращается False, которое в математическом контексте равно 0.
5️⃣Итоговое сложение: 5 + 0 даёт результат 5.
Почему это важно
С одной стороны, это позволяет писать изящные счётчики вроде sum(x > 0 for x in lst). С другой стороны, неочевидное смешивание булевых значений и арифметики может запутать читателя кода, поэтому злоупотреблять этим не стоит.
Разбор по шагам
1️⃣Вызывается test()
2️⃣Выполняется блок try, доходим до return 1
3️⃣Python запоминает, что нужно вернуть 1, но перед выходом из функции обязан выполнить блок finally
4️⃣Входим в finally → встречаем return 2
5️⃣Запомненное значение 1 безвозвратно отбрасывается
6️⃣Функция завершается с возвратом 2
7️⃣print(2) выводит 2
Почему это важно
Никогда не используйте операторы управления потоком (return, break, continue) внутри finally. Это антипаттерн: он может скрывать исключения и ломать ожидаемую логику возврата значений из функции.
Объяснение по шагам
1️⃣Цикл for i in range(3) запускается: i принимает значения 0, 1, 2
2️⃣На каждой итерации создаётся лямбда lambda: i — но она не запоминает текущее значение i, а сохраняет лишь ссылку на имя i
3️⃣Список funcs теперь содержит три функции, каждая смотрит на одно и то же имя i
4️⃣Цикл завершился — переменная i в области видимости равна 2
5️⃣f() вызывается для первой лямбды → ищет i → находит 2 → возвращает 2
6️⃣То же самое для второй и третьей лямбды
7️⃣print([2, 2, 2]) выводит [2, 2, 2]
Почему это важно
Классическая ловушка при создании коллбэков в цикле. Чтобы зафиксировать значение в момент создания, используйте аргумент по умолчанию: lambda i=i: i — он вычисляется сразу при создании функции.
