Ответ
Monkey patching — это техника динамического изменения (замены) атрибутов или методов классов и модулей во время выполнения программы. Это позволяет модифицировать поведение стороннего кода без изменения его исходников.
Этот подход является мощным, но рискованным, так как может приводить к трудноотлавливаемым ошибкам и несовместимости при обновлении библиотек.
Основные сценарии использования:
- Тестирование: Замена внешних зависимостей (например, сетевых запросов или работы с базой данных) на mock-объекты. Библиотека
unittest.mock.patchактивно использует этот механизм. - Исправление багов: Временное исправление ошибок в сторонней библиотеке до выхода официального патча.
- Добавление функциональности: Расширение возможностей существующего класса.
Пример:
import datetime
# Сохраняем оригинальный метод
_original_datetime_now = datetime.datetime.now
def patched_now():
# Всегда возвращаем фиксированную дату
return datetime.datetime(2023, 1, 1, 12, 0, 0)
# Применяем monkey patch
datetime.datetime.now = patched_now
# Теперь любой вызов datetime.datetime.now() вернет нашу дату
print(f"Текущее время после патча: {datetime.datetime.now()}")
# Вывод: Текущее время после патча: 2023-01-01 12:00:00
# Возвращаем оригинальное поведение (важно для чистоты кода)
datetime.datetime.now = _original_datetime_now Ответ 18+ 🔞
О, слушай, вот эта штука — monkey patching, ну, как обезьяна с гаечным ключом под капотом, блядь. Суть в том, что ты можешь на лету, прямо во время работы программы, хуяк — и подменить методы или атрибуты у классов и модулей. То есть, не лезешь в исходники, не переписываешь библиотеку, а просто, внаглую, впендюриваешь своё.
Мощная, конечно, вещь, но, ёпта, с ней как с огнём — можно и всю хату спалить. Потому что если накосячить, то ошибки будут такие, что их потом с микроскопом искать, а при обновлении библиотеки всё может накрыться медным тазом, потому что твой патч может просто перестать работать.
Ну и где это, блядь, применяют?
- Тестирование, сука. Самый частый случай. Нужно, чтобы какой-нибудь запрос в интернет не ходил, а возвращал тестовые данные. Берешь и подменяешь эту функцию на свою заглушку. Библиотека
unittest.mock.patch— это она и есть, просто в красивом фраке. - Исправление косяков. Нашел баг в чужой библиотеке, а фикс выйдет только через месяц. Ну, ты не ждешь, как лох, а пишешь временный патч и вманиваешь его, чтобы твой код не падал.
- Добавление фич. Хочется, чтобы у стандартного класса была ещё какая-то приблуда. Просто добавляешь ему новый метод, и все, ты — царь и бог этого класса.
Смотри, как это выглядит на практике:
import datetime
# Сохраняем оригинальный метод на всякий пожарный, а то потом не найдёшь
_original_datetime_now = datetime.datetime.now
def patched_now():
# А тут мы, хитрая жопа, всегда будем возвращать одну и ту же дату
return datetime.datetime(2023, 1, 1, 12, 0, 0)
# ВАУ! Магия! Подменяем стандартный метод на наш
datetime.datetime.now = patched_now
# Теперь любой вызов datetime.datetime.now() вернёт нашу фиктивную дату
print(f"Текущее время после патча: {datetime.datetime.now()}")
# Вывод: Текущее время после патча: 2023-01-01 12:00:00
# И главное, блядь, не забудь вернуть как было, особенно в тестах!
datetime.datetime.now = _original_datetime_now
Вот и вся магия, ебать мои старые костыли. Главное — не увлекаться, а то получится такой спагетти-код, что сам через неделю не поймёшь, что и куда ты тут напатчил.