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

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

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

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

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

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

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

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

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

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

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

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

Все подборки
  • Python14 550
  • Облачные технологии10 965
  • QA вакансии3 255
  • Android1 702
  • Инженер данных1 270
  • Продакт-менеджер586

Разработка

  • Backend вакансии1 657
  • iOS1 575
  • AI вакансии798
  • Fullstack вакансии672
  • Frontend вакансии578
  • Mobile вакансии30

По стеку

  • Go7 978
  • Java5 162
  • Node.js1 622
  • Kotlin1 384
  • Rust1 326
  • .NET1 258
  • PHP538
  • C++386
  • C#356

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

  • Kubernetes6 272
  • Linux-инфраструктура4 763
  • DevOps вакансии4 488
  • Terraform / IaC3 459
  • Мониторинг и Observability1 587
  • CI/CD1 482
  • SRE458
  • Кибербезопасность127

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

  • Аналитик данных683
  • Бизнес-аналитик638
  • Data Scientist622
  • Системный аналитик92

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

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

По регионам

  • Вакансии в США34 823
  • Вакансии в Европе15 244
  • Работа в России3 882
  • Вакансии в Канаде3 408

По формату

  • Удалённые вакансии54 624
  • Релокация в США34 823
  • Гибридная работа9 269
  • Офисная работа6 545

По уровню

  • Senior вакансии31 197
  • Middle вакансии14 037
  • Junior вакансии5 059

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

Все компании
  • Wise194 вакансии
  • Rakuten189 вакансий
  • ASML164 вакансии
  • Grab134 вакансии
  • Celonis45 вакансий
  • Spotify37 вакансий
  • Infobip28 вакансий
  • Adyen27 вакансий
  • Monzo19 вакансий
  • Darktrace17 вакансий

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

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

Что такое monkey patching и когда это допустимо?

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

Monkey patching — динамическая замена атрибутов модуля или класса во время выполнения. Допустим в тестах (через unittest.mock.patch) и для срочных hotfix сторонних библиотек. В production-коде почти всегда лучше заменить наследованием или композицией.

Что такое monkey patching

Monkey patching — это динамическая замена атрибутов модуля, класса или экземпляра во время выполнения программы. В Python это возможно потому, что атрибуты хранятся в словарях (__dict__) и могут быть перезаписаны в любой момент.

import requests

# Оригинальная функция
original_get = requests.get

def patched_get(url: str, **kwargs):
    print(f"[PATCH] GET {url}")
    return original_get(url, **kwargs)

# Заменяем метод в модуле
requests.get = patched_get

# Теперь все вызовы requests.get() будут логироваться
requests.get("https://example.com")  # [PATCH] GET https://example.com

Основные сценарии применения

1. Тестирование с unittest.mock.patch

Самое частое и правильное применение — изоляция внешних зависимостей в тестах:

from unittest.mock import patch, MagicMock
import pytest

# Модуль под тестом
# myapp/services.py
# def fetch_user(user_id: int) -> dict:
#     response = requests.get(f"/api/users/{user_id}")
#     return response.json()

def test_fetch_user_success():
    mock_response = MagicMock()
    mock_response.json.return_value = {"id": 1, "name": "Alice"}
    mock_response.status_code = 200

    # patch заменяет requests.get только внутри блока with
    with patch("myapp.services.requests.get", return_value=mock_response):
        from myapp.services import fetch_user
        result = fetch_user(1)

    assert result == {"id": 1, "name": "Alice"}
    # После выхода из контекста requests.get восстановлен


# Декоратор — более распространённый стиль
@patch("myapp.services.requests.get")
def test_fetch_user_404(mock_get):
    mock_get.return_value.status_code = 404
    mock_get.return_value.json.return_value = {"error": "not found"}
    from myapp.services import fetch_user
    result = fetch_user(999)
    assert "error" in result

2. Hotfix сторонней библиотеки

Когда баг в зависимости критичен, а обновление невозможно или опасно:

import some_library.utils as _utils

_original = _utils.parse_date

def _fixed_parse_date(value: str):
    # Обходим баг с timezone-aware строками
    if value.endswith("Z"):
        value = value[:-1] + "+00:00"
    return _original(value)

_utils.parse_date = _fixed_parse_date

# ВАЖНО: комментарий с номером issue и плановой датой удаления
# TODO(2026-Q3): удалить после обновления some_library >= 2.5.0
# Ref: https://github.com/some_library/issues/123

3. Добавление метода к сторонним классам

from datetime import date

def _to_iso_week(self: date) -> str:
    return f"{self.isocalendar().year}-W{self.isocalendar().week:02d}"

# Добавляем метод к встроенному классу через патч модуля
# (не к самому date — он написан на C и не изменяем напрямую)
date.to_iso_week = _to_iso_week  # type: ignore[attr-defined]

print(date(2026, 1, 5).to_iso_week())  # '2026-W01'

Правильный способ: контекстный менеджер для локального патча

from contextlib import contextmanager
from typing import Any, Generator
import time

@contextmanager
def mock_time(ts: float) -> Generator[None, None, None]:
    original = time.time
    time.time = lambda: ts  # type: ignore[assignment]
    try:
        yield
    finally:
        time.time = original

with mock_time(1_700_000_000.0):
    print(time.time())  # 1700000000.0
print(time.time())  # реальное время восстановлено

Когда monkey patching недопустим

  • Изменение поведения в production-коде без явного флага или конфигурации
  • Патч глобального состояния в многопоточном коде без синхронизации
  • Замена методов у типов, реализованных на C (list.append, dict.__setitem__) — в большинстве случаев это либо не работает, либо ломает интерпретатор

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

  • Порядок импорта имеет значение — если другой модуль уже сделал from requests import get, ваш патч на requests.get его не затронет. Патчить нужно в том пространстве имён, где атрибут используется: patch("mymodule.requests.get").
  • Отсутствие восстановления при ошибке — без try/finally или контекстного менеджера патч остаётся при исключении. Всегда используйте unittest.mock.patch или явный finally.
  • Гонки в многопоточном коде — глобальный патч на уровне модуля виден всем потокам. Если тест патчит time.sleep в одном потоке, другой поток тоже получит заглушку.
  • Трудная отладка — стек вызовов после патча указывает на подменённую функцию, а не оригинальную. Добавляйте явные комментарии и логирование в patch-функции.
  • Несовместимость с type checkers — mypy и pyright не знают о динамических патчах. Требуются # type: ignore или стабы.
  • Побочные эффекты на другие тесты — если патч не изолирован через patch или monkeypatch (pytest), он может «протечь» в соседние тесты. Всегда используйте autouse фикстуры или scope-ограниченные патчи.
  • C-расширения ограничены — атрибуты типов, определённых в C (int, str, list), защищены и не принимают произвольные атрибуты: AttributeError: cannot set '_x' attribute of immutable type 'int'.
  • Альтернативы предпочтительнее — в production-коде вместо патча лучше использовать dependency injection, Protocol/ABC для замены реализации, или паттерн Adapter для обёртки стороннего API.

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

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

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

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

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

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

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

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

Источники

  • https://docs.python.org/3/tutorial/datastructures.html
  • https://docs.python.org/3/reference/datamodel.html

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

Pythontechnical-reasoning