Я пытаюсь понять, что такое исправление обезьяны или исправление обезьяны?
Это что-то вроде перегрузки или делегирования методов / операторов?
Есть ли что-то общее с этими вещами?
python
terminology
monkeypatching
Сергей Башаров
источник
источник
Monkey patching is a technique to add, modify, or suppress the default behavior of a piece of code at runtime without changing its original source code.
Ответы:
Нет, это не похоже ни на одну из этих вещей. Это просто динамическая замена атрибутов во время выполнения.
Например, рассмотрим класс, у которого есть метод
get_data
. Этот метод выполняет внешний поиск (например, в базе данных или веб-API), и различные другие методы в классе вызывают его. Однако в модульном тесте вы не хотите зависеть от внешнего источника данных - поэтому вы динамически заменяетеget_data
метод заглушкой, которая возвращает некоторые фиксированные данные.Поскольку классы Python являются изменяемыми, а методы - это просто атрибуты класса, вы можете делать это сколько угодно - и фактически вы можете даже заменить классы и функции в модуле точно таким же образом.
Но, как отметил комментатор , соблюдайте осторожность при установке обезьян:
Если что-то еще, кроме вашей тестовой логики
get_data
, также вызовет, это также вызовет замену, исправленную обезьяной, а не оригинал - что может быть хорошим или плохим. Просто будь осторожен.Если существует некоторая переменная или атрибут, который также указывает на
get_data
функцию к моменту ее замены, этот псевдоним не изменит своего значения и будет продолжать указывать на оригиналget_data
. (Почему? Python просто привязывает имяget_data
в вашем классе к другому объекту функции; на другие привязки имен это никак не влияет.)источник
pointing to the original get_data function
? Вы имеете в виду, когда вы сохраняете функцию внутри переменной, если кто-то изменяет эту функцию, переменная будет продолжать указывать на старую?get_data
, вы привязываете имяget_data
к фиктивной функции. Если какое-либо другое имя где-либо еще в программе связано с ранее известной функцией-функциейget_data
, ничто не изменится для этого другого имени.Простой пример выглядит так:
Источник: страница MonkeyPatch на вики Zope.
источник
Проще говоря, исправление обезьян вносит изменения в модуль или класс во время работы программы.
Пример использования
В документации Pandas есть пример исправления обезьян:
Чтобы разбить это, сначала мы импортируем наш модуль:
Затем мы создаем определение метода, которое существует несвязанным и свободным вне рамок любых определений классов (поскольку различие между функцией и несвязанным методом довольно бессмысленно, Python 3 устраняет несвязанный метод):
Затем мы просто присоединяем этот метод к классу, на котором мы хотим его использовать:
И тогда мы можем использовать метод в экземпляре класса и удалить метод, когда закончим:
Будьте осторожны
Если вы используете искажение имени (добавление к атрибуту префикса с двойным подчеркиванием, которое меняет имя, и которое я не рекомендую), вам придется вручную изменять имя, если вы делаете это. Так как я не рекомендую искажение имени, я не буду демонстрировать это здесь.
Пример тестирования
Как мы можем использовать эти знания, например, при тестировании?
Скажем, нам нужно смоделировать вызов извлечения данных из внешнего источника данных, который приводит к ошибке, потому что мы хотим обеспечить правильное поведение в таком случае. Мы можем обезопасить структуру данных, чтобы обеспечить такое поведение. (Таким образом, используя аналогичное имя метода, предложенное Дэниелом Роузманом :)
И когда мы проверяем его на поведение, которое основано на том, что этот метод вызывает ошибку, если он правильно реализован, мы получим такое поведение в результатах теста.
Простое выполнение вышеизложенного изменит
Structure
объект на весь жизненный цикл процесса, поэтому вы захотите использовать настройки и разрывы в своих тестах юнитов, чтобы избежать этого, например:(Хотя в приведенном выше порядке, вероятно , было бы лучше идеи использовать
mock
библиотеку для исправления кода.mock
«Spatch
декоратора будет меньше ошибок , чем делать выше, что потребует больше строк коды и , следовательно , больше возможностей для внедрения ошибок Я еще не рассмотрел код,mock
но я думаю, что он использует патч обезьян аналогичным образом.)источник
Согласно Википедии :
источник
Во-первых: исправление обезьян - злой хак (на мой взгляд).
Он часто используется для замены метода на уровне модуля или класса пользовательской реализацией.
Самым распространенным вариантом использования является добавление обходного пути для ошибки в модуле или классе, когда вы не можете заменить исходный код. В этом случае вы заменяете «неправильный» код с помощью «обезьяньих патчей» реализацией внутри вашего собственного модуля / пакета.
источник
Патч обезьяны может быть сделан только на динамических языках, примером чего является Python. Изменение метода во время выполнения вместо обновления определения объекта является одним из примеров, аналогичным образом, добавление атрибутов (методов или переменных) во время выполнения считается исправлением обезьяны. Это часто делается при работе с модулями, для которых у вас нет источника, так что определения объектов не могут быть легко изменены.
Это считается плохим, потому что это означает, что определение объекта не полностью или точно не описывает, как он на самом деле ведет себя.
источник
Исправление обезьян - это повторное открытие существующих классов или методов в классе во время выполнения и изменение поведения, которое следует использовать осторожно, или вы должны использовать его только тогда, когда это действительно необходимо.
Поскольку Python является динамическим языком программирования, классы изменчивы, поэтому вы можете открыть их и изменить или даже заменить.
источник
Для получения дополнительной информации, пожалуйста, обратитесь [1]: https://medium.com/@nagillavenkatesh1234/monkey-patching-in-python-explained-with-examples-25eed0aea505
источник