что такое monkey патчинг

Хороший плохой манкипатчинг

что такое monkey патчинг. Смотреть фото что такое monkey патчинг. Смотреть картинку что такое monkey патчинг. Картинка про что такое monkey патчинг. Фото что такое monkey патчинг

Почему это так плохо или не так уж и плохо? — интересуется Сергей.

Ответить на этот вопрос, не начав холивар, так же сложно, как провести Шорты после Вадима. Манкипатчинг работает, поэтому нельзя сказать, что он плох, но важно помнить, что с ним очень легко выстрелить себе в ногу.

Манкипатчинг — это когда мы изменяем код в рантайме, то есть по ходу выполнения программы. Например, добавляем несуществующие методы в массив или переопределяем какую-нибудь глобальную функцию.

Манкипатчинг идеально подходит для одноразовых задач, когда нужен реверс-инжиниринг. Например, если нужно отладить решение проблемы или разово собрать какую-нибудь аналитику, это подойдет, но это заведомо одноразовые подходы.

Если говорить о промышленном коде, то неосторожно обращаясь с манки-патчами, можно сломать работу встроенных объектов, которые будут использоваться во всей программе. Представьте, что вы зачем-то, изменили поведение функции setTimeout. Внешне, она работает так же, но дополнительно эта функция решает какие-то другие задачи, например, сохраняет контекст.

window.setTimeout = function( fn, timeout, ctx ) < initialTimeout( function() < fn.call(ctx); >, timeout); >

Конечно, в вашем коде setTimeout будет работать так, как вам нужно, но вы не можете гарантировать, что в других местах, где он используется все будет работать так же гладко. Есть и более экстремальные примеры, например, раньше в JS можно было переопределить даже undefined и window.

Получается, что с манкипатчингом нужно быть очень осторожным и придерживаться определенных правил.

Во-первых, добавлять новое лучше чем изменять старое. Изменять поведение уже встроенных в язык методов плохо, потому что они могут использоваться где-то ещё кроме вашего кода. А вот, добавить что-то новое, чем кто-то другой вряд ли додумается воспользоваться — относительно безопасно. Например, добавить в массивы метод их перемешивания. Правда, через какое-то время, в массиве может появиться такой метод — стандарты развиваются, а браузеры быстро их подхватывают.

Во-вторых нужно тщательно тестировать патчи. Это общий совет для разработчиков, но когда речь идет о манкипатчах, нужно быть вдвойне осторожным, потому что в одном месте они могут помочь, а в другом только навредить. При написании манкипатчей нужно тестировать не только на сам патч, но и хорошо бы проверить, не сломалось ли чего-нибудь на уровне всего приложения.

И наконец, лучше использовать патчи как временные решения. Поскольку манкипатчи могут навредить, от них нужно отказываться, как только это становится возможным.

По этим правилам создаются полифилы — патчи, которые добавляют поддержку новых фич в старые браузеры. Согласитесь, как сильно меняет название отношение к подходу. Были обезьяньи исправления, а стал универсальный наполнитель. Были непонятные изменения встроенных объектов, а стало исправление проблем с поддержкой новых стандартов.

Источник

Monkey Patching в Python: объяснение с примерами

В этой статье рассказано о monkey patching (обезьяний патч см wiki), то есть о том, как динамически обновлять поведение кода во время выполнения. Мы также рассмотрим некоторые полезные примеры monkey patching в Python.

Что такое monkey patching?

Это метод, используемый для динамического изменения поведения фрагмента кода во время выполнения.

Зачем он нужен?

Он позволяет изменить или расширять поведение библиотек, модулей, классов или методов во время выполнения без фактического изменения исходного кода.

Когда он используется?

Ситуации в которых может понадобиться monkey patching:

Предупреждение: почему monkey patching следует очень осторожно использовать

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

Monkey patching в Python

В Python модули или классы похожи на любые другие изменяемые объекты, такие как списки, то есть мы можем изменять их или их атрибуты, включая функции или методы во время выполнения. Давайте рассмотрим несколько примеров.

Пример 1: Замена значения атрибута модуля

В качестве основного примера давайте рассмотрим, как мы можем обновить атрибут модуля. Мы будем обновлять значение «пи» в модуле math, чтобы его точность была уменьшена до 3,14.

Обратите внимание, как мы создали резервную копию исходного значения перед нашими вычислениями, а затем вернули исправление в конце. Это хорошая практика, особенно в тестах, чтобы не испортить весь набор тестов.

Пример 2: Расширения поведения метода

В этом примере мы увидим, как расширить поведение метода. Мы рассмотрим, как обновить встроенный метод печати в Python3, чтобы включить метку времени.

Пример 3: Изменение поведение метода

Теперь давайте посмотрим, как полностью изменить поведение метода. Это может быть особенно полезно в модульных тестах для моделирования сложных методов с внешними зависимостями (сеть, база данных и т. д.). Здесь мы рассмотрим, как заменить один метод другим.

Пример 4: Изменение атрибута класса

До сих пор мы обновляли атрибуты или методы на уровне модулей. Теперь давайте посмотрим, как обновить атрибут класса. Обратите внимание, что таким образом мы изменяем атрибут самого класса, поэтому все его экземпляры получат исправленный атрибут.

Пример 5: Изменяем атрибуты конкретного экземпляра

В предыдущем примере показано, как обновить атрибут класса. В этом примере мы увидим, как обновить только атрибут конкретного экземпляра.

Обратите внимание, что мы использовали метод MethodType из модуля types в Python, чтобы связать исправленный метод только с одним экземпляром. Это гарантирует, что другие экземпляры класса не будут затронуты.

Пример 6: Заменяем целый класс

Теперь давайте посмотрим, как мы могли бы изменить класс. Так как класс также является просто объектом, мы можем заменить его любым другим объектом.

Пример 7: Заменяем целый модуль

В качестве последнего примера, давайте посмотрим, как мы можем заменить целый модуль. Это работает так же, как и с любым другим объектом в Python.

Заключение

Monkey patching — это хорошая техника замены/обновления любых сущностей в Python. Однако, как мы уже говорили, он имеет свои недостатки и должен использоваться там где он реально необходим.

Источник

Хороший плохой манкипатчинг

Нам часто задают вопросы по технологиям в письмах и сообщениях — мы с удовольствием отвечаем. Но в таком случае ответ получает один человек, а он мог бы пригодиться многим.

Поэтому мы решили еженедельно разбирать по одному вопросу, буквально за пять минут.

что такое monkey патчинг. Смотреть фото что такое monkey патчинг. Смотреть картинку что такое monkey патчинг. Картинка про что такое monkey патчинг. Фото что такое monkey патчинг

Сегодня вопрос про разработку от Сергея, отвечает наш преподаватель Игорь Алексеенко:

Манкипатчинг — почему это так плохо или не так уж и плохо?

Ответить на этот вопрос, не начав холивар, сложно. Манкипатчинг работает, поэтому нельзя сказать, что он плох, но важно помнить, что с ним очень легко выстрелить себе в ногу.

Манкипатчинг — это когда мы изменяем код в рантайме, то есть по ходу выполнения программы. Например, добавляем несуществующие методы в массив или переопределяем какую-нибудь глобальную функцию.

Манкипатчинг идеально подходит для одноразовых задач, когда нужен реверс-инжиниринг. Например, если нужно отладить решение проблемы или разово собрать какую-нибудь аналитику, это подойдёт, но это заведомо одноразовые подходы.

Если говорить о промышленном коде, то неосторожно обращаясь с манки-патчами, можно сломать работу встроенных объектов, которые будут использоваться во всей программе. Представьте, что вы зачем-то, изменили поведение функции setTimeout. Внешне, она работает так же, но дополнительно эта функция решает какие-то другие задачи, например, сохраняет контекст.

Конечно, в вашем коде setTimeout будет работать так, как вам нужно, но вы не можете гарантировать, что в других местах, где он используется всё будет работать так же гладко. Есть и более экстремальные примеры, например, раньше в JavaScript можно было переопределить даже undefined и window.

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

Добавлять новое лучше, чем изменять старое.

Изменять поведение уже встроенных в язык методов плохо, потому что они могут использоваться где-то ещё кроме вашего кода. А вот, добавить что-то новое, чем кто-то другой вряд ли додумается воспользоваться — относительно безопасно. Например, добавить в массивы метод их перемешивания. Правда, через какое-то время, в массиве может появиться такой метод — стандарты развиваются, а браузеры быстро их подхватывают.

Нужно тщательно тестировать патчи.

Это общий совет для разработчиков, но когда речь идёт о манкипатчах, нужно быть вдвойне осторожным, потому что в одном месте они могут помочь, а в другом только навредить. При написании манкипатчей нужно тестировать не только на сам патч, но и хорошо бы проверить, не сломалось ли чего-нибудь на уровне всего приложения.

Лучше использовать патчи как временные решения.

Поскольку манкипатчи могут навредить, от них нужно отказываться, как только это становится возможным.

По этим правилам создаются полифилы — патчи, которые добавляют поддержку новых фич в старые браузеры. Согласитесь, как сильно меняет название отношение к подходу. Были обезьяньи исправления, а стал универсальный наполнитель. Были непонятные изменения встроенных объектов, а стало исправление проблем с поддержкой новых стандартов.

Кажется, что полифилы — это хорошая идея: подключаешь полифил и вне зависимости от того, какой у пользователя браузер, в коде можно использовать новые штуки, например, Fetch для HTTP-запросов, Promise или Object.entries для итерирования по объектам.

Но и в этом подходе есть проблемы:

Надо что-то делать с теми браузерами, которые уже поддерживают то, что вы патчите.

Идеально бы отключать патчи для тех браузеров, в которых фича уже поддерживается. Обычно, разработчики полифилов берут это на себя, но этот момент нужно проверять.

Если речь идёт об уже принятом стандарте, который работает как минимум в одном браузере и его поддержка в остальных — это просто вопрос времени, то проблемы нет. Но если говорить о ещё обсуждающемся стандарте, лучше не создавать полифила, потому что программисты могут начать использовать его и привыкнут к нему, а разработчики стандартов не смогут внести в стандарт какие-то улучшения, потому что стандарт будет закреплён де-факто.

В таких ситуациях лучше использовать функции-обёртки, которые иногда называются понифилами. В принципе, они позволяют делать то же самое что и полифилы, но явно. А ещё у них нет проблем со стандартами: например, популярная библиотека Lodash выросла как раз из обёртки над неработающими итераторами в массивах. Ребята добавили в библиотеку forEach, map и прочие some, every, но не привязывались к стандарту и поэтому у них были изначально развязаны руки. Через какое-то время они добавили другие удобные методы для массивов и коллекций, такие как shuffle, unique, flatten и другие. Несмотря на то что итераторы в массивах поддерживаются уже давно, Lodash успешно развивается.

Ещё, функции-понифилы проще тестировать. Очень сложно до конца протестировать полифил. Если подключить его там же где, выполняются тесты, ваш патч может изменить код самого фреймворка, что может повлиять на тестирование. А если тестировать логику полифилов отдельно, то непонятно будет, правильно ли они подключаются.

Ещё в разной среде ваши тесты будут работать по-разному, потому что в одних средах патч сработает, в других — нет. У понифилов таких проблем нет: вы всегда знаете что тестируете, они подключаются и работают явно.

Подытожим

Плох ли манкипатчинг? Судя по тому, что он работает, он не так плох, но при его использовании нужно помнить, что с ним проще сломать чей-то чужой код, его сложнее тестировать и можно вообще забыть, что он используется.

Источник

What is monkey patching?

I am trying to understand, what is monkey patching or a monkey patch?

Is that something like methods/operators overloading or delegating?

Does it have anything common with these things?

что такое monkey патчинг. Смотреть фото что такое monkey патчинг. Смотреть картинку что такое monkey патчинг. Картинка про что такое monkey патчинг. Фото что такое monkey патчинг

что такое monkey патчинг. Смотреть фото что такое monkey патчинг. Смотреть картинку что такое monkey патчинг. Картинка про что такое monkey патчинг. Фото что такое monkey патчинг

8 Answers 8

No, it’s not like any of those things. It’s simply the dynamic replacement of attributes at runtime.

But, as a commenter pointed out, use caution when monkeypatching:

что такое monkey патчинг. Смотреть фото что такое monkey патчинг. Смотреть картинку что такое monkey патчинг. Картинка про что такое monkey патчинг. Фото что такое monkey патчинг

A MonkeyPatch is a piece of Python code which extends or modifies other code at runtime (typically at startup).

A simple example looks like this:

Source: MonkeyPatch page on Zope wiki.

что такое monkey патчинг. Смотреть фото что такое monkey патчинг. Смотреть картинку что такое monkey патчинг. Картинка про что такое monkey патчинг. Фото что такое monkey патчинг

What is a monkey patch?

Simply put, monkey patching is making changes to a module or class while the program is running.

Example in usage

There’s an example of monkey-patching in the Pandas documentation:

To break this down, first we import our module:

Next we create a method definition, which exists unbound and free outside the scope of any class definitions (since the distinction is fairly meaningless between a function and an unbound method, Python 3 does away with the unbound method):

Next we simply attach that method to the class we want to use it on:

And then we can use the method on an instance of the class, and delete the method when we’re done:

Caveat for name-mangling

If you’re using name-mangling (prefixing attributes with a double-underscore, which alters the name, and which I don’t recommend) you’ll have to name-mangle manually if you do this. Since I don’t recommend name-mangling, I will not demonstrate it here.

Testing Example

How can we use this knowledge, for example, in testing?

Say we need to simulate a data retrieval call to an outside data source that results in an error, because we want to ensure correct behavior in such a case. We can monkey patch the data structure to ensure this behavior. (So using a similar method name as suggested by Daniel Roseman:)

And when we test it for behavior that relies on this method raising an error, if correctly implemented, we’ll get that behavior in the test results.

Just doing the above will alter the Structure object for the life of the process, so you’ll want to use setups and teardowns in your unittests to avoid doing that, e.g.:

(While the above is fine, it would probably be a better idea to use the mock library to patch the code. mock ‘s patch decorator would be less error prone than doing the above, which would require more lines of code and thus more opportunities to introduce errors. I have yet to review the code in mock but I imagine it uses monkey-patching in a similar way.)

Источник

Python monkey-patching like a boss

что такое monkey патчинг. Смотреть фото что такое monkey патчинг. Смотреть картинку что такое monkey патчинг. Картинка про что такое monkey патчинг. Фото что такое monkey патчинг

Feb 17, 2019 · 4 min read

If you work in a big project, most likely you will meet situations, when you would like to change/improve used third-party library behaviour, and you try to modify it from your project. This is called monkey-patching and it is usually associated with something not obvious, which would like to avoid. Nevertheless it’s a part of development process. And let’s see how to use monkey-patch valuably in Python.

Imagine that there is a third-party library my_lib with function func inside which behaviour I would like to change. And let’s go!

Note! Code below was verified with Python v3.7.

Patching module entities

To p atch module (or class) variables or functions is easy, because Python doesn’t create protected or private entities and in most cases it’s possible to get reference to them.

Third-party library structure:

2. Patch value, when entities are in separated modules.

3. Patch variable, when function is imported to package level from internal module.

The same sample as above, except one small thing, which changes all.

And patching doesn’t work then:

Let’s look at the details.

In order to avoid such case, after VAR monkey-patching it needs to forcibly reload all affected packages and modules. In order to make it, it needs to delete them from cache of loaded modules with next function:

And now it works also for package level too:

For most cases it’s enough and can be used also to monkey-patch functions, classes, methods with the same approach. Main idea is to move reference from original to patched entity before its import or forcibly to reimport entity after patching.

But let’s play further!

Patching closed entities

Patching of closed entities inside functions is a bit tricky but also possible if to use ast and inspect modules.

It’s more complicated than above variants, isn’t? Let’s learn it step-by-step:

2. Patch closed function.

3. Patch closed function inside class method.

Here direct ast.parse won’t work with inspect.getsource because method has additional indentation, which can’t be parsed:

Let’s patch with indentation cleaning:

Memory address changing

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *