Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+1 440новых вакансий за сутки·54 706вакансий открыто сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании5 625
РезюмеAIПодготовкаСтатьи
BoostТарифыBoost
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 397 кандидатов открыты к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python8 748
  • Облачные технологии6 616
  • QA вакансии2 169
  • Android1 320
  • Инженер данных872
  • Продакт-менеджер302

Разработка

  • iOS1 232
  • Backend вакансии1 204
  • AI вакансии543
  • Fullstack вакансии497
  • Frontend вакансии417
  • Mobile вакансии28

По стеку

  • Go5 212
  • Java3 116
  • Kotlin1 090
  • Node.js995
  • Rust845
  • .NET661
  • PHP320
  • C++271
  • C#208

DevOps и инфраструктура

  • Kubernetes3 913
  • Linux-инфраструктура2 852
  • DevOps вакансии2 678
  • Terraform / IaC2 167
  • Мониторинг и Observability1 066
  • CI/CD923
  • SRE301
  • Кибербезопасность26

Аналитика и данные

  • Аналитик данных533
  • Data Scientist436
  • Бизнес-аналитик400
  • Системный аналитик68

Другие направления

  • Проджект-менеджер90
  • UI/UX дизайн70
  • Ручное тестирование14

По регионам

  • Вакансии в США26 186
  • Вакансии в Европе10 369
  • Работа в России3 628
  • Вакансии в Канаде2 306

По формату

  • Удалённые вакансии43 484
  • Релокация в США26 186
  • Гибридная работа5 597
  • Офисная работа4 383

По уровню

  • Senior вакансии22 724
  • Middle вакансии11 726
  • Junior вакансии3 874

Сейчас нанимают

Все компании
  • Wise190 вакансий
  • Rakuten189 вакансий
  • ASML164 вакансии
  • Grab135 вакансий
  • Celonis45 вакансий
  • Spotify37 вакансий
  • Infobip28 вакансий
  • Adyen26 вакансий
  • Monzo19 вакансий
  • Darktrace16 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме PythonВсе вопросы
PythonJuniorКодинг

Как работают замыкания (closures) в Python? Приведите пример.

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

Замыкание — функция, которая захватывает переменные из объемлющей области видимости; Python хранит их в __closure__ как cell-объекты и продолжает удерживать после возврата внешней функции.

Базовый пример

def make_multiplier(factor: int):  # внешняя функция
    def multiply(x: int) -> int:   # замыкание захватывает factor
        return x * factor
    return multiply


double = make_multiplier(2)
triple = make_multiplier(3)

print(double(10))   # 20
print(triple(10))   # 30

# Посмотреть захваченные переменные:
print(double.__closure__)          # (<cell at 0x...>,)
print(double.__closure__[0].cell_contents)  # 2

Как работают замыкания

Когда вложенная функция обращается к переменной из объемлющего scope, Python «захватывает» эту переменную в cell-объект. Cell живёт дольше фрейма внешней функции и доступен через атрибут __closure__ вложенной функции. Это и есть замыкание (closure).

Практический пример: фабрика логгеров

import logging
from typing import Callable


def make_logger(module_name: str) -> Callable[[str], None]:
    logger = logging.getLogger(module_name)  # захватывается замыканием

    def log(message: str) -> None:
        logger.info("[%s] %s", module_name, message)

    return log


auth_log = make_logger("auth")
jobs_log = make_logger("jobs")

auth_log("user logged in")    # [auth] user logged in
jobs_log("new job posted")    # [jobs] new job posted

Классическая ловушка: замыкание в цикле

# НЕВЕРНО: все функции захватят одну и ту же переменную i
funcs_bad = [lambda: i for i in range(3)]
print([f() for f in funcs_bad])  # [2, 2, 2] — не [0, 1, 2]!

# ПРАВИЛЬНО: зафиксировать значение через default-аргумент
funcs_ok = [lambda i=i: i for i in range(3)]
print([f() for f in funcs_ok])   # [0, 1, 2]

# Или через фабрику
def make_func(i: int):
    def f() -> int:
        return i
    return f

funcs_factory = [make_func(i) for i in range(3)]
print([f() for f in funcs_factory])  # [0, 1, 2]

nonlocal — изменение захваченной переменной

def make_counter(start: int = 0):
    count = start

    def increment(by: int = 1) -> int:
        nonlocal count   # без nonlocal — UnboundLocalError
        count += by
        return count

    def reset() -> None:
        nonlocal count
        count = start

    return increment, reset


inc, rst = make_counter(10)
print(inc())    # 11
print(inc(5))   # 16
rst()
print(inc())    # 11

Замыкания vs классы

# Замыкание — лаконично для простого состояния
def rate_limiter(max_calls: int, window: float):
    import time
    calls: list[float] = []

    def allow() -> bool:
        now = time.monotonic()
        # Удаляем вызовы вне окна
        while calls and now - calls[0] > window:
            calls.pop(0)
        if len(calls) < max_calls:
            calls.append(now)
            return True
        return False

    return allow


check = rate_limiter(max_calls=3, window=1.0)
for _ in range(5):
    print(check())  # True True True False False

Подводные камни

  • Замыкание в цикле захватывает ссылку на переменную, а не её значение в момент создания — классическая ошибка с lambda в цикле.
  • Без nonlocal попытка присвоить значение захваченной переменной внутри вложенной функции вызывает UnboundLocalError.
  • Захваченные объекты удерживаются в памяти пока живёт замыкание — это может привести к утечкам при хранении больших объектов (DataFrame, открытые файлы).
  • Замыкания не сериализуются через pickle по умолчанию — проблема при использовании с multiprocessing.
  • Глубокое вложение замыканий ухудшает читаемость; если состояний много — лучше использовать класс.
  • Дебаггинг замыканий сложнее: трейсбек не показывает захваченные переменные явно; используйте fn.__closure__[i].cell_contents.

Частые вопросы на собеседовании

  • Что такое truthy и falsy значения в Python?
  • Когда использовать threading?
  • Что такое type hints и зачем они нужны?
  • Как работает yield?

Типичные ошибки

  • Описывать closures только как термин и не показывать механизм на минимальном примере.
  • Игнорировать ошибки, пустые данные, конкурентный доступ или границы транзакции.
  • Не связывать поведение с официальным контрактом Python и реальной эксплуатацией.

Что проверяет интервьюер

  • Объясняет closures через последовательность действий, а не через набор ключевых слов.
  • Приводит короткий кодовый пример или production-сценарий с ожидаемым поведением.
  • Называет хотя бы один риск: производительность, безопасность, транзакции, память или сопровождение.

Как вы знаете этот вопрос?

Проверить себя по теме Python →

Источники

  • https://docs.python.org/3/reference/datamodel.html
  • https://docs.python.org/3/howto/descriptor.html

Связанные темы

Pythonimplementationtechnical-reasoning

Вакансии с этим навыком

Python вакансии
  • Senior Data Engineer I - Global KYC & Onboarding
  • Lead Cloud Engineer (Azure) — Interview Experts Needed (#5499)
  • Senior Python Engineer (Embedded project) (#5821)
  • Middle AI/ML Engineer (#5827)
  • Voice AI Engineer (Real-Time Speech) (#5861)