{"id":6757,"date":"2023-08-30T01:40:07","date_gmt":"2023-08-30T01:40:07","guid":{"rendered":"https:\/\/www.pythontutorial.net\/?page_id=6757"},"modified":"2025-03-27T13:58:24","modified_gmt":"2025-03-27T13:58:24","slug":"python-monkey-patching","status":"publish","type":"page","link":"https:\/\/www.pythontutorial.net\/advanced-python\/python-monkey-patching\/","title":{"rendered":"Python Monkey Patching"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn the concept of monkey patching in Python, when to use it, and how to apply it effectively.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='introduction-to-python-monkey-patching'>Introduction to Python monkey patching <a href=\"#introduction-to-python-monkey-patching\" class=\"anchor\" id=\"introduction-to-python-monkey-patching\" title=\"Anchor for Introduction to Python monkey patching\">#<\/a><\/h2>\n\n\n\n<p>Monkey patching is a technique that allows you to modify or extend the behavior of existing <a href=\"https:\/\/www.pythontutorial.net\/python-basics\/python-module\/\">modules<\/a>, <a href=\"https:\/\/www.pythontutorial.net\/python-oop\/python-class\/\">classes<\/a>, or <a href=\"https:\/\/www.pythontutorial.net\/python-basics\/python-functions\/\">functions<\/a> at runtime without changing the original source code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id='applying-monkey-patching'>Applying monkey patching <a href=\"#applying-monkey-patching\" class=\"anchor\" id=\"applying-monkey-patching\" title=\"Anchor for Applying monkey patching\">#<\/a><\/h3>\n\n\n\n<p>To apply the monkey patching technique, you follow these steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>First, identify the target that can be a module, class, method, or function you want to patch.<\/li>\n\n\n\n<li>Second, create your patch by writing code to add, modify, or replace existing logic.<\/li>\n\n\n\n<li>Third, apply the patch by using an assignment to apply it to the target. The patch will overwrite or extend the existing behavior.<\/li>\n<\/ul>\n\n\n\n<p>While monkey patching is a powerful tool, you should use it carefully to avoid unexpected behaviors.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id='monkey-patching-example'>Monkey patching example <a href=\"#monkey-patching-example\" class=\"anchor\" id=\"monkey-patching-example\" title=\"Anchor for Monkey patching example\">#<\/a><\/h3>\n\n\n\n<p>Suppose you have <code>MyClass<\/code> class that only has an <code>__init__()<\/code> method:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Robot<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, name)<\/span>:<\/span>\n        self.name = name<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To extend the behavior of the <code>Robot<\/code> class at runtime without changing the <code>Robot<\/code> class, you can use the monkey patching technique.<\/p>\n\n\n\n<p>Image that you need to extend a behavior that allows the Robot&#8217;s instances to speak. Here are the steps to do so:<\/p>\n\n\n\n<p>First, define a function called <code>add_speech<\/code> that accepts a class as the parameter:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">add_speech<\/span><span class=\"hljs-params\">(cls)<\/span>:<\/span>\n    cls.speak = <span class=\"hljs-keyword\">lambda<\/span> self, message: print(message)\n    <span class=\"hljs-keyword\">return<\/span> cls<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>add_speech()<\/code> function adds the <code>speak()<\/code> method by adding a speak attribute to the <code>cls<\/code> class and assigning a <a href=\"https:\/\/www.pythontutorial.net\/python-basics\/python-lambda-expressions\/\">lambda expression<\/a> and returning the class. The lambda expression accepts a message and displays it to the console.<\/p>\n\n\n\n<p>Second, patch the <code>Robot<\/code> class by passing it to the <code>add_speech()<\/code> method:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">Robot = add_speech(Robot)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>After this line of code, the <code>Robot<\/code> class will have the <code>speak()<\/code> method. <\/p>\n\n\n\n<p class=\"note\">Note that you can use the <code>add_speech()<\/code> function to patch any classes, not just the <code>Robot<\/code> class.<\/p>\n\n\n\n<p>Third, create a new instance of the <code>Robot<\/code> class and call the <code>speak()<\/code> method:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">robot = Robot(<span class=\"hljs-string\">'Optimus Prime'<\/span>)\nrobot.speak(<span class=\"hljs-string\">'Hi'<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Put it all together:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">add_speech<\/span><span class=\"hljs-params\">(cls)<\/span>:<\/span>\n    cls.speak = <span class=\"hljs-keyword\">lambda<\/span> self, message: print(message)\n    <span class=\"hljs-keyword\">return<\/span> cls\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Robot<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, name)<\/span>:<\/span>\n        self.name = name\n\n\nRobot = add_speech(Robot)\n\nrobot = Robot(<span class=\"hljs-string\">'Optimus Prime'<\/span>)\nrobot.speak(<span class=\"hljs-string\">'Hi'<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><a href=\"https:\/\/www.pythontutorial.net\/playground\/?q=ZGVmIGFkZF9zcGVlY2goY2xzKToKICAgIGNscy5zcGVhayA9IGxhbWJkYSBzZWxmLCBtZXNzYWdlOiBwcmludChtZXNzYWdlKQogICAgcmV0dXJuIGNscwoKCmNsYXNzIFJvYm90OgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUpOgogICAgICAgIHNlbGYubmFtZSA9IG5hbWUKCgpSb2JvdCA9IGFkZF9zcGVlY2goUm9ib3QpCgpyb2JvdCA9IFJvYm90KCdPcHRpbXVzIFByaW1lJykKcm9ib3Quc3BlYWsoJ0hpJyk%3D\" target=\"_blank\" rel=\"noreferrer noopener\">Try it<\/a><\/p>\n\n\n\n<p>If you run the program, you&#8217;ll see the following output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">Hi<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Since this line of code is a decorator:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">Robot = add_speech(Robot)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>you can remove it and use the <a href=\"https:\/\/www.pythontutorial.net\/advanced-python\/python-decorators\/\">decorator<\/a> syntax:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">@add_speech<\/span>\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Robot<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, name)<\/span>:<\/span>\n        self.name = name<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The new code will look like:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">add_speech<\/span><span class=\"hljs-params\">(cls)<\/span>:<\/span>\n    cls.speak = <span class=\"hljs-keyword\">lambda<\/span> self, message: print(message)\n    <span class=\"hljs-keyword\">return<\/span> cls\n\n\n<span class=\"hljs-meta\">@add_speech<\/span>\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Robot<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, name)<\/span>:<\/span>\n        self.name = name\n\n\nrobot = Robot(<span class=\"hljs-string\">'Optimus Prime'<\/span>)\nrobot.speak(<span class=\"hljs-string\">'Hi'<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><a href=\"https:\/\/www.pythontutorial.net\/playground\/?q=ZGVmIGFkZF9zcGVlY2goY2xzKToKICAgIGNscy5zcGVhayA9IGxhbWJkYSBzZWxmLCBtZXNzYWdlOiBwcmludChtZXNzYWdlKQogICAgcmV0dXJuIGNscwoKCkBhZGRfc3BlZWNoCmNsYXNzIFJvYm90OgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUpOgogICAgICAgIHNlbGYubmFtZSA9IG5hbWUKCgpyb2JvdCA9IFJvYm90KCdPcHRpbXVzIFByaW1lJykKcm9ib3Quc3BlYWsoJ0hpJyk%3D\" target=\"_blank\" rel=\"noreferrer noopener\">Try it<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='when-to-use-monkey-patching'>When to use monkey patching <a href=\"#when-to-use-monkey-patching\" class=\"anchor\" id=\"when-to-use-monkey-patching\" title=\"Anchor for When to use monkey patching\">#<\/a><\/h2>\n\n\n\n<p>In practice, you should use monkey patching only when necessary because it can make code harder to understand and debug.<\/p>\n\n\n\n<p>For example, if you use a third-party library and it has an urgent bug that you cannot wait for official release. In this case, you can use the monkey patching to apply quick fixes while waiting for a proper solution.<\/p>\n\n\n\n<p>Another scenario is that you want to add functionality to classes that you don&#8217;t control and you cannot use other techniques like inheritance or composition, the monkey patching is useful in this case.<\/p>\n\n\n\n<p>In practice, you&#8217;ll find monkey patching in the mock library such as the standard <code><a href=\"https:\/\/www.pythontutorial.net\/python-unit-testing\/python-patch\/\">unittest.mock<\/a><\/code> module. The <code>unittest.mock<\/code> module has <code><a href=\"https:\/\/www.pythontutorial.net\/python-unit-testing\/python-patch\/\">patch()<\/a><\/code> method that temporarily replaces a target with a mock object.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='summary'>Summary <a href=\"#summary\" class=\"anchor\" id=\"summary\" title=\"Anchor for Summary\">#<\/a><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The monkey patching technique in Python allows you to dynamically modify or extend existing code at runtime without changing the original code.<\/li>\n\n\n\n<li>Use the monkey patching technique if you have a good reason to do so.<\/li>\n<\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"6757\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/advanced-python\/python-monkey-patching\/\"\n\t\t\t\tdata-post-title=\"Python Monkey Patching\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"6757\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/advanced-python\/python-monkey-patching\/\"\n\t\t\t\tdata-post-title=\"Python Monkey Patching\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\t\t\t<input type=\"button\" name=\"wth-submit\" class=\"wth-btn wth-btn-submit\" id=\"wth-submit\" \/>\n\t\t\t<input type=\"button\" class=\"wth-btn wth-btn-cancel\" value=\"Cancel\" \/>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn the concept of monkey patching in Python, when to use it, and how to apply it effectively.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":757,"menu_order":12,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-6757","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/6757","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/comments?post=6757"}],"version-history":[{"count":3,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/6757\/revisions"}],"predecessor-version":[{"id":7117,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/6757\/revisions\/7117"}],"up":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/757"}],"wp:attachment":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/media?parent=6757"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}