{"id":1741,"date":"2024-01-29T21:41:09","date_gmt":"2024-01-29T21:41:09","guid":{"rendered":"https:\/\/www.w3computing.com\/articles\/?p=1741"},"modified":"2024-01-29T21:41:12","modified_gmt":"2024-01-29T21:41:12","slug":"write-custom-magic-methods-python-classes","status":"publish","type":"post","link":"https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/","title":{"rendered":"How to Write Custom Magic Methods for Python Classes"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Welcome to the deep dive into the world of Python classes, specifically focusing on the nifty and somewhat mystical realm of magic methods. If you&#8217;ve been playing around with Python for a while, you&#8217;re likely familiar with the basics of classes. They&#8217;re like the blueprints of objects, right? But here\u2019s the thing: sometimes, those blueprints need a bit of a personal touch. That&#8217;s where customizing Python classes comes into play, and it&#8217;s a game-changer in how we interact with these objects.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, you might be wondering, \u201cWhat\u2019s so special about customizing classes?\u201d Well, think of it this way: it&#8217;s like having a secret toolkit that lets you modify how objects behave under different operations. Want to change how your objects are printed? Or maybe you\u2019re curious about altering how operators work with them? This is where Python&#8217;s magic methods shine.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Magic methods are special methods that start and end with double underscores, often referred to as \u201cdunder\u201d methods. You&#8217;ve probably seen <code>__init__<\/code> (the constructor method) in action. These methods are the secret sauce that lets you add all sorts of functionalities to your classes, making them more intuitive and elegant to use.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this tutorial, we\u2019re going to explore these magic methods in depth. We\u2019ll start with the basics, like <code>__init__<\/code>, <code>__str__<\/code>, and <code>__repr__<\/code>, and gradually move to more complex ones that allow for operator overloading and even making your objects behave like containers or context managers. And the best part? We&#8217;re going to learn all of this through practical, hands-on examples.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, gear up for an exciting journey into customizing Python classes using magic methods. By the end of this, you\u2019ll not only have a deeper understanding of these methods but also how to wield them effectively to make your Python code more efficient and expressive. Let\u2019s get started!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Understanding Magic Methods<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Alright folks, let\u2019s roll up our sleeves and get into the crux of this guide &#8211; the world of magic methods in Python. Trust me, understanding these will be like unlocking a new level of Python proficiency!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What are Magic Methods?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">First off, let\u2019s define what we mean by &#8216;magic methods&#8217;. In the simplest terms, magic methods are special methods in Python that start and end with double underscores (hence the nickname &#8220;dunder&#8221; methods). Examples include <code>__init__<\/code>, <code>__str__<\/code>, and <code>__repr__<\/code>. They&#8217;re like hidden levers in Python classes; you pull them, and something interesting happens.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Significance of Magic Methods<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Why are they significant, you ask? Well, magic methods are the backbone of a lot of the Python internals. They provide a way to intercept and implement behavior for built-in Python operations. Say you want to define how Python should print your object, or maybe how arithmetic operations should work with it. Magic methods are your go-to for this. They&#8217;re how Python handles not just construction and representation, but also addition, subtraction, attribute access, and much more.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Distinguishing Magic Methods from Regular Methods<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Now, how do these differ from your regular methods? Regular methods are the ones you define to perform specific actions. They&#8217;re like workers, doing the tasks you explicitly ask them to do. Magic methods, on the other hand, are more like undercover agents. They work behind the scenes, getting called when you use built-in Python functions like <code>len()<\/code> or when operations like addition or string representation are needed. They&#8217;re automatically triggered by Python&#8217;s internals, which is kind of cool, right?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Commonly Used Magic Methods<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s talk about some of the stars of the magic method world:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>__init__<\/code>: The constructor. It&#8217;s called when an object is created, letting you set up your object with all the right attributes.<\/li>\n\n\n\n<li><code>__str__<\/code>: Defines the human-readable string representation of an object. This is what gets called when you print an object.<\/li>\n\n\n\n<li><code>__repr__<\/code>: Sets up the object\u2019s official string representation. It\u2019s more for developers to understand what the object is about. Ideally, it should be clear and unambiguous.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">These are just the tip of the iceberg. There are magic methods for arithmetic operations (<code>__add__<\/code>, <code>__mul__<\/code>, etc.), container methods (<code>__len__<\/code>, <code>__getitem__<\/code>, etc.), and so many more. Each of these has a unique role in making your classes behave in a Pythonic and intuitive way.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Diving into Basic Magic Methods<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Alright, let&#8217;s dive into the ocean of Python&#8217;s magic methods! We&#8217;ll start with the basics: <code>__init__<\/code>, <code>__del__<\/code>, <code>__str__<\/code>, and <code>__repr__<\/code>. These are like the fundamental spells in your Python wizardry book.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>__init__<\/code> and <code>__del__<\/code>: Constructors and Destructors<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">The Constructor &#8211; <code>__init__<\/code><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>__init__<\/code> method is like the welcoming committee of your class. It&#8217;s the constructor that gets called when you create a new instance of a class. Think of it as setting up a new room in your house &#8211; you decide what furniture goes in.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s a simple example:<\/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\">Book<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, title, author)<\/span>:<\/span>\r\n        self.title = title\r\n        self.author = author\r\n\r\nmy_book = Book(<span class=\"hljs-string\">\"Python Magic\"<\/span>, <span class=\"hljs-string\">\"Wizardly Pythonista\"<\/span>)\r\nprint(<span class=\"hljs-string\">f\"Book: <span class=\"hljs-subst\">{my_book.title}<\/span>, Author: <span class=\"hljs-subst\">{my_book.author}<\/span>\"<\/span>)<\/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 class=\"wp-block-paragraph\">In this example, whenever a <code>Book<\/code> is created, <code>__init__<\/code> sets up its <code>title<\/code> and <code>author<\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">The Destructor &#8211; <code>__del__<\/code><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">On the flip side, <code>__del__<\/code> is the destructor. It\u2019s like the cleanup crew that comes in when an object is about to be destroyed. It\u2019s less commonly used, but it&#8217;s handy for resources like closing files or releasing memory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s how you might see it:<\/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-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Book<\/span>:<\/span>\r\n    <span class=\"hljs-comment\"># ... (previous code)<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__del__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        print(<span class=\"hljs-string\">f\"<span class=\"hljs-subst\">{self.title}<\/span> by <span class=\"hljs-subst\">{self.author}<\/span> is being deleted.\"<\/span>)\r\n\r\nmy_book = Book(<span class=\"hljs-string\">\"Python Magic\"<\/span>, <span class=\"hljs-string\">\"Wizardly Pythonista\"<\/span>)\r\n<span class=\"hljs-keyword\">del<\/span> my_book<\/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 class=\"wp-block-paragraph\">When <code>my_book<\/code> is deleted, the destructor prints out a message.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>__str__<\/code> and <code>__repr__<\/code>: Object Representation<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><code>__str__<\/code>: User-Friendly Representation<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>__str__<\/code> method is all about readability. It&#8217;s used to print a user-friendly representation of an object, which is super useful for debugging.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example time:<\/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\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Book<\/span>:<\/span>\r\n    <span class=\"hljs-comment\"># ... (previous code)<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__str__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">f\"<span class=\"hljs-subst\">{self.title}<\/span> by <span class=\"hljs-subst\">{self.author}<\/span>\"<\/span>\r\n\r\nmy_book = Book(<span class=\"hljs-string\">\"Python Magic\"<\/span>, <span class=\"hljs-string\">\"Wizardly Pythonista\"<\/span>)\r\nprint(my_book)<\/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 class=\"wp-block-paragraph\">When you print <code>my_book<\/code>, <code>__str__<\/code> defines what gets shown.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>__repr__<\/code>: Official Representation<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><code>__repr__<\/code>, on the other hand, is more about an unambiguous representation of the object, ideally one that you could use to recreate the object.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s how it looks:<\/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\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Book<\/span>:<\/span>\r\n    <span class=\"hljs-comment\"># ... (previous code)<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__repr__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">f\"Book('<span class=\"hljs-subst\">{self.title}<\/span>', '<span class=\"hljs-subst\">{self.author}<\/span>')\"<\/span>\r\n\r\nmy_book = Book(<span class=\"hljs-string\">\"Python Magic\"<\/span>, <span class=\"hljs-string\">\"Wizardly Pythonista\"<\/span>)\r\nprint(repr(my_book))<\/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 class=\"wp-block-paragraph\">Using <code>repr(my_book)<\/code>, you get a string that you could use to recreate the object.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Operator Overloading with Magic Methods<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Alright, team, let&#8217;s level up our Python game with some operator overloading magic! Operator overloading lets you define custom behavior for operators like <code>+<\/code>, <code>-<\/code>, <code>==<\/code>, and more, making your classes even more powerful and intuitive to use.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Concept of Operator Overloading in Python<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Operator overloading in Python is all about giving special meanings to standard operators like <code>+<\/code>, <code>-<\/code>, or <code>*<\/code> when they&#8217;re used with objects of a certain class. Think of it like teaching your objects a new language where they understand these operators in their own unique way. This is done through specific magic methods.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Magic Methods for Arithmetic Operators<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Arithmetic Magic<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s start with the arithmetic operators. Say you&#8217;ve got a class representing vectors and you want to add them using the <code>+<\/code> operator. Python won&#8217;t know how to add these custom objects unless you tell it to, and that&#8217;s where magic methods like <code>__add__<\/code> come in.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s an example:<\/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-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Vector<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, x, y)<\/span>:<\/span>\r\n        self.x = x\r\n        self.y = y\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__add__<\/span><span class=\"hljs-params\">(self, other)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> Vector(self.x + other.x, self.y + other.y)\r\n\r\nv1 = Vector(<span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>)\r\nv2 = Vector(<span class=\"hljs-number\">5<\/span>, <span class=\"hljs-number\">7<\/span>)\r\nv3 = v1 + v2\r\nprint(<span class=\"hljs-string\">f\"Vector Sum: (<span class=\"hljs-subst\">{v3.x}<\/span>, <span class=\"hljs-subst\">{v3.y}<\/span>)\"<\/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 class=\"wp-block-paragraph\">In this case, <code>__add__<\/code> lets you use <code>+<\/code> to add two <code>Vector<\/code> objects.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Other Arithmetic Operators<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Similarly, you can define behavior for subtraction (<code>__sub__<\/code>), multiplication (<code>__mul__<\/code>), and more.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Magic Methods for Comparison Operators<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Comparison Magic<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Now, let&#8217;s talk comparisons. Say you have a class and you want to compare objects of that class using <code>==<\/code> or <code>&lt;<\/code>. You&#8217;ll need the magic methods <code>__eq__<\/code> for equality and <code>__lt__<\/code> for &#8220;less than&#8221;, respectively.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s see an example with a simple <code>Box<\/code> class:<\/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\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Box<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, size)<\/span>:<\/span>\r\n        self.size = size\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__eq__<\/span><span class=\"hljs-params\">(self, other)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> self.size == other.size\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__lt__<\/span><span class=\"hljs-params\">(self, other)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> self.size &lt; other.size\r\n\r\nbox1 = Box(<span class=\"hljs-number\">5<\/span>)\r\nbox2 = Box(<span class=\"hljs-number\">10<\/span>)\r\nprint(<span class=\"hljs-string\">f\"Box1 == Box2? <span class=\"hljs-subst\">{box1 == box2}<\/span>\"<\/span>)\r\nprint(<span class=\"hljs-string\">f\"Box1 &lt; Box2? <span class=\"hljs-subst\">{box1 &lt; box2}<\/span>\"<\/span>)<\/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 class=\"wp-block-paragraph\">Here, <code>__eq__<\/code> allows for a comparison using <code>==<\/code>, and <code>__lt__<\/code> for <code>&lt;<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Advanced Magic Methods<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ready to explore some advanced magic in Python? We&#8217;re going to look at magic methods that let your classes mimic container types and manage context. This is like giving your classes superpowers to interact more deeply with Python&#8217;s features.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Container Type Emulation<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Emulating Container Types<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Python has various built-in container types like lists, tuples, and dictionaries. With magic methods, you can make your own class behave like one of these containers. This is done using methods like <code>__len__<\/code>, <code>__getitem__<\/code>, and <code>__setitem__<\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">A Custom Container Class Example<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s create a custom class that behaves like a simple list. We&#8217;ll call it <code>CustomList<\/code>.<\/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\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CustomList<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, elements)<\/span>:<\/span>\r\n        self.elements = elements\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__len__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> len(self.elements)\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__getitem__<\/span><span class=\"hljs-params\">(self, key)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> self.elements&#91;key]\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__setitem__<\/span><span class=\"hljs-params\">(self, key, value)<\/span>:<\/span>\r\n        self.elements&#91;key] = value\r\n\r\nmy_list = CustomList(&#91;<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>])\r\nprint(len(my_list))         <span class=\"hljs-comment\"># Output: 3<\/span>\r\nprint(my_list&#91;<span class=\"hljs-number\">1<\/span>])           <span class=\"hljs-comment\"># Output: 2<\/span>\r\nmy_list&#91;<span class=\"hljs-number\">1<\/span>] = <span class=\"hljs-number\">200<\/span>\r\nprint(my_list&#91;<span class=\"hljs-number\">1<\/span>])           <span class=\"hljs-comment\"># Output: 200<\/span><\/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 class=\"wp-block-paragraph\">Here, <code>__len__<\/code> lets you use <code>len(my_list)<\/code>, <code>__getitem__<\/code> for accessing items using <code>my_list[index]<\/code>, and <code>__setitem__<\/code> for setting items with <code>my_list[index] = value<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Context Management<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">The Concept of Context Management<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Context managers are another cool feature of Python. They are typically used with the <code>with<\/code> statement to encapsulate standard setup and teardown actions. The magic methods <code>__enter__<\/code> and <code>__exit__<\/code> make a class a context manager.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Context Manager Class Example<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s say we want to create a class that manages opening and closing a file. We&#8217;ll call it <code>FileOpener<\/code>.<\/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-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">FileOpener<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, filename, mode)<\/span>:<\/span>\r\n        self.file = open(filename, mode)\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__enter__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> self.file\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__exit__<\/span><span class=\"hljs-params\">(self, exc_type, exc_val, exc_tb)<\/span>:<\/span>\r\n        self.file.close()\r\n\r\n<span class=\"hljs-keyword\">with<\/span> FileOpener(<span class=\"hljs-string\">'example.txt'<\/span>, <span class=\"hljs-string\">'w'<\/span>) <span class=\"hljs-keyword\">as<\/span> f:\r\n    f.write(<span class=\"hljs-string\">'Hello, Python magic!'<\/span>)\r\n\r\n<span class=\"hljs-comment\"># The file is automatically closed after the with block<\/span><\/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 class=\"wp-block-paragraph\">In this example, <code>__enter__<\/code> opens the file and returns it. After the <code>with<\/code> block, <code>__exit__<\/code> is automatically called to close the file.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Customizing Attribute Access<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now let&#8217;s dive into another fascinating aspect of Python&#8217;s magic methods: customizing attribute access. This is like teaching your class some neat tricks on how to handle its attributes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Magic Methods for Attribute Access and Assignment<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">The Basics of Attribute Magic<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">In Python, attributes are the variables that belong to a class. Normally, when you access or set these attributes, Python just does its thing in the background. But what if you want more control over this process? That&#8217;s where <code>__getattr__<\/code>, <code>__setattr__<\/code>, and <code>__delattr__<\/code> come into play.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>__getattr__<\/code> is called when an attribute that doesn&#8217;t exist is accessed.<\/li>\n\n\n\n<li><code>__setattr__<\/code> is invoked when an attribute is set.<\/li>\n\n\n\n<li><code>__delattr__<\/code> is used when an attribute is deleted.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Custom Attribute Handling Example<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s create a class called <code>SmartPhone<\/code> where we&#8217;ll control attribute access and assignment.<\/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-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">SmartPhone<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, brand)<\/span>:<\/span>\r\n        self._attributes = {<span class=\"hljs-string\">\"brand\"<\/span>: brand}\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__getattr__<\/span><span class=\"hljs-params\">(self, item)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> self._attributes.get(item, <span class=\"hljs-string\">f\"<span class=\"hljs-subst\">{item}<\/span> not found\"<\/span>)\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__setattr__<\/span><span class=\"hljs-params\">(self, key, value)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> key == <span class=\"hljs-string\">\"brand\"<\/span>:\r\n            super().__setattr__(key, value)\r\n        <span class=\"hljs-keyword\">else<\/span>:\r\n            self._attributes&#91;key] = value\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__delattr__<\/span><span class=\"hljs-params\">(self, item)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> item <span class=\"hljs-keyword\">in<\/span> self._attributes:\r\n            <span class=\"hljs-keyword\">del<\/span> self._attributes&#91;item]\r\n        <span class=\"hljs-keyword\">else<\/span>:\r\n            print(<span class=\"hljs-string\">f\"<span class=\"hljs-subst\">{item}<\/span> cannot be deleted\"<\/span>)\r\n\r\nphone = SmartPhone(<span class=\"hljs-string\">\"TechCorp\"<\/span>)\r\nprint(phone.brand)     <span class=\"hljs-comment\"># Output: TechCorp<\/span>\r\nphone.model = <span class=\"hljs-string\">\"X100\"<\/span>\r\nprint(phone.model)     <span class=\"hljs-comment\"># Output: X100<\/span>\r\n<span class=\"hljs-keyword\">del<\/span> phone.model\r\nprint(phone.model)     <span class=\"hljs-comment\"># Output: model not found<\/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 class=\"wp-block-paragraph\">Here, <code>__getattr__<\/code> provides a default message when a non-existing attribute is accessed. <code>__setattr__<\/code> controls how attributes are set, and <code>__delattr__<\/code> manages attribute deletion.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Implementing Attribute Management in a Controlled Way<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Managing attributes this way allows you to implement validations, logging, and other useful features when attributes are accessed, set, or deleted. It makes your classes smarter and gives you a higher level of control over how they behave. For instance, you can prevent certain attributes from being changed or deleted, or trigger actions when they are.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Remember, with great power comes great responsibility. Overriding these methods can make your class behave in unexpected ways if not done carefully. It&#8217;s important to ensure that these methods are implemented in a way that&#8217;s intuitive and doesn&#8217;t confuse anyone using your class.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Callable Objects<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Hello again, Python adventurers! Now, let\u2019s turn our attention to an intriguing Python feature: transforming objects into callables. This is like giving your object a special power &#8211; the ability to act like a function!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>__call__<\/code> Method: Making Objects Callable<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">The Magic of <code>__call__<\/code><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">In Python, functions are first-class citizens, meaning they can be passed around and used as objects. But what if you want your object to behave like a function? That\u2019s where the <code>__call__<\/code> method comes into play. By defining <code>__call__<\/code>, you can call an instance of your class as if it were a function.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Creating a Callable Object Example<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s create a simple <code>Multiplier<\/code> class. You can call an instance of this class with a number, and it will return the number multiplied by a predefined factor.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" 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\">Multiplier<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, factor)<\/span>:<\/span>\r\n        self.factor = factor\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__call__<\/span><span class=\"hljs-params\">(self, x)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> x * self.factor\r\n\r\ndouble = Multiplier(<span class=\"hljs-number\">2<\/span>)\r\ntriple = Multiplier(<span class=\"hljs-number\">3<\/span>)\r\n\r\nprint(double(<span class=\"hljs-number\">5<\/span>))  <span class=\"hljs-comment\"># Output: 10<\/span>\r\nprint(triple(<span class=\"hljs-number\">3<\/span>))  <span class=\"hljs-comment\"># Output: 9<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><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 class=\"wp-block-paragraph\">In this example, <code>double<\/code> and <code>triple<\/code> are instances of <code>Multiplier<\/code> that you can use like functions. When you call <code>double(5)<\/code>, it&#8217;s effectively calling <code>double.__call__(5)<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Power and Flexibility of Callable Objects<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Using the <code>__call__<\/code> method can make your classes much more flexible and intuitive. Imagine a scenario where you have objects that naturally correspond to a process or action. By making these objects callable, you&#8217;re aligning your code&#8217;s structure with its conceptual model, which can make your code much easier to understand and maintain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It also opens up creative possibilities for how you structure your code. For example, you could create classes that represent complex mathematical functions, request handlers in a web application, or strategies in a strategy pattern.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, remember to use this power wisely. If overused or used inappropriately, it could lead to code that is harder to understand and maintain. The key is to use callable objects in situations where it makes your code more intuitive and aligns with the object&#8217;s conceptual role.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Best Practices in Implementing Magic Methods<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Welcome back, Python pros! As we\u2019ve explored the fascinating world of magic methods, you&#8217;ve probably started to see their immense power and versatility. But with great power comes great responsibility. Let&#8217;s talk about the best practices for implementing these methods, when to use them, the pitfalls to avoid, and how they can impact performance.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">When to Use Magic Methods<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Enhancing Pythonic Elegance<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Magic methods should be used to make your classes integrate seamlessly with Python&#8217;s built-in features, making them more intuitive and &#8216;Pythonic&#8217;. For example, use <code>__str__<\/code> for readable string representations or <code>__add__<\/code> for adding objects.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Avoid Overuse<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Only implement magic methods when they make logical sense for your class. Don&#8217;t force a class to fit a magic method if it doesn&#8217;t conceptually align. For instance, don&#8217;t implement <code>__add__<\/code> for a class where addition doesn&#8217;t make sense.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Common Pitfalls and How to Avoid Them<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Breaking Expectations<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Magic methods can lead to unexpected behaviors if not used correctly. For example, overloading operators in a way that deviates from their conventional meaning can confuse users of your class.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Solution<\/strong>: Stick to the established meanings and behaviors of operators and methods. If you&#8217;re overloading an operator, make sure it&#8217;s intuitive and aligns with how the operator is used in other contexts.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Infinite Recursion<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Accidental infinite recursion can occur, especially with <code>__setattr__<\/code> and <code>__getattr__<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Solution<\/strong>: In <code>__setattr__<\/code>, use <code>super().__setattr__()<\/code> to set attributes directly on the instance&#8217;s dictionary, avoiding recursion. In <code>__getattr__<\/code>, ensure you handle missing attributes correctly to avoid endless loops.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Performance Considerations<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Impact on Speed<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Some magic methods can have a performance impact. For instance, <code>__getattr__<\/code> can slow down attribute access, as it&#8217;s called every time an attribute isn&#8217;t found in the object&#8217;s <code>__dict__<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Solution<\/strong>: Use magic methods judiciously and test the performance of your class, especially if it&#8217;s used in performance-critical parts of your application.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Memory Overhead<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Implementing certain magic methods can increase the memory footprint of your objects. This is particularly true for methods that add additional attributes or complex behaviors.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Solution<\/strong>: Be mindful of the memory overhead when adding magic methods. If your objects are created frequently or in large numbers, this overhead can add up.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Real-world Applications of Magic Methods<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now, let&#8217;s connect the dots between the theory of magic methods and their practical, real-world applications. Magic methods aren&#8217;t just cool tricks; they play pivotal roles in many Pythonic designs, enhancing the functionality and readability of classes. Let\u2019s explore some instances where magic methods shine in the real world.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Examples of Effective Use of Magic Methods<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">1. Data Models and ORM (Object-Relational Mapping)<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">In ORM frameworks like SQLAlchemy or Django ORM, magic methods are extensively used to represent database models. For example, <code>__repr__<\/code> provides a clear, concise representation of database records, which is incredibly useful for debugging and logging.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">2. Numerical and Scientific Computing<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Libraries like NumPy and Pandas heavily rely on magic methods. They overload arithmetic operators (<code>__add__<\/code>, <code>__mul__<\/code>, etc.) to allow for elegant and intuitive operations on arrays and dataframes, mimicking the syntax of mathematical equations.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">3. Custom Containers<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">In libraries that implement custom container types (like collections in the Python Standard Library), magic methods are used to handle item assignment, retrieval, and iteration (<code>__setitem__<\/code>, <code>__getitem__<\/code>, <code>__iter__<\/code>, etc.). This makes these containers behave just like native Python types.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">4. Context Managers for Resource Management<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Magic methods <code>__enter__<\/code> and <code>__exit__<\/code> are used in context managers, which are widely used for resource management. For instance, the <code>with open(file) as f<\/code> pattern for file handling in Python is an excellent example of this.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How Magic Methods Improve Python Class Design<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Enhancing Intuitiveness and Readability<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Magic methods allow objects to behave like native Python objects. This makes the code more intuitive and easier to read. When a class supports <code>+<\/code> for addition or <code>with<\/code> for context management, it aligns with Python&#8217;s philosophy of simplicity and elegance.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Encouraging Consistent Behavior<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">They encourage consistency in how objects are manipulated. For instance, implementing <code>__eq__<\/code> ensures that objects of the same class can be compared consistently using the <code>==<\/code> operator, following the principle of least surprise.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Boosting Flexibility<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Magic methods make classes more flexible. They allow the same class to behave differently under different circumstances, like changing the behavior of arithmetic operators or customizing attribute access.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Facilitating Better Abstraction<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">By abstracting complex actions into simple operator expressions or standard method calls, magic methods allow for more abstract and high-level coding. This abstraction can lead to cleaner, more maintainable code.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">In conclusion, magic methods are not just about adding syntactic sugar to your classes. They are about embracing and extending Python&#8217;s core philosophies, making your classes more Pythonic, intuitive, and robust. Whether it&#8217;s in numerical computing, web frameworks, or custom data structures, magic methods enable Python developers to write code that&#8217;s not just functional but also clean and expressive.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Welcome to the deep dive into the world of Python classes, specifically focusing on the nifty and somewhat mystical realm of magic methods. If you&#8217;ve been playing around with Python for a while, you&#8217;re likely familiar with the basics of classes. They&#8217;re like the blueprints of objects, right? But here\u2019s the thing: sometimes, those blueprints [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4,6],"tags":[],"class_list":["post-1741","post","type-post","status-publish","format-standard","category-programming-languages","category-python","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to Write Custom Magic Methods for Python Classes<\/title>\n<meta name=\"description\" content=\"Magic methods are special methods that start and end with double underscores, often referred to as \u201cdunder\u201d methods.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Write Custom Magic Methods for Python Classes\" \/>\n<meta property=\"og:description\" content=\"Magic methods are special methods that start and end with double underscores, often referred to as \u201cdunder\u201d methods.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/\" \/>\n<meta property=\"article:published_time\" content=\"2024-01-29T21:41:09+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-29T21:41:12+00:00\" \/>\n<meta name=\"author\" content=\"w3compadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"w3compadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/write-custom-magic-methods-python-classes\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/write-custom-magic-methods-python-classes\\\/\"},\"author\":{\"name\":\"w3compadmin\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"headline\":\"How to Write Custom Magic Methods for Python Classes\",\"datePublished\":\"2024-01-29T21:41:09+00:00\",\"dateModified\":\"2024-01-29T21:41:12+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/write-custom-magic-methods-python-classes\\\/\"},\"wordCount\":2740,\"commentCount\":0,\"articleSection\":[\"Programming Languages\",\"Python\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/write-custom-magic-methods-python-classes\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/write-custom-magic-methods-python-classes\\\/\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/write-custom-magic-methods-python-classes\\\/\",\"name\":\"How to Write Custom Magic Methods for Python Classes\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\"},\"datePublished\":\"2024-01-29T21:41:09+00:00\",\"dateModified\":\"2024-01-29T21:41:12+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"description\":\"Magic methods are special methods that start and end with double underscores, often referred to as \u201cdunder\u201d methods.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/write-custom-magic-methods-python-classes\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/write-custom-magic-methods-python-classes\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/write-custom-magic-methods-python-classes\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Articles Home\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming Languages\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"How to Write Custom Magic Methods for Python Classes\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\",\"name\":\"Developer Articles Hub\",\"description\":\"\",\"alternateName\":\"Developer Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\",\"name\":\"w3compadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"contentUrl\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"caption\":\"w3compadmin\"},\"sameAs\":[\"http:\\\/\\\/w3computing.com\\\/articles\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Write Custom Magic Methods for Python Classes","description":"Magic methods are special methods that start and end with double underscores, often referred to as \u201cdunder\u201d methods.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/","og_locale":"en_US","og_type":"article","og_title":"How to Write Custom Magic Methods for Python Classes","og_description":"Magic methods are special methods that start and end with double underscores, often referred to as \u201cdunder\u201d methods.","og_url":"https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/","article_published_time":"2024-01-29T21:41:09+00:00","article_modified_time":"2024-01-29T21:41:12+00:00","author":"w3compadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"w3compadmin","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/#article","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/"},"author":{"name":"w3compadmin","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"headline":"How to Write Custom Magic Methods for Python Classes","datePublished":"2024-01-29T21:41:09+00:00","dateModified":"2024-01-29T21:41:12+00:00","mainEntityOfPage":{"@id":"https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/"},"wordCount":2740,"commentCount":0,"articleSection":["Programming Languages","Python"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/","url":"https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/","name":"How to Write Custom Magic Methods for Python Classes","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/#website"},"datePublished":"2024-01-29T21:41:09+00:00","dateModified":"2024-01-29T21:41:12+00:00","author":{"@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"description":"Magic methods are special methods that start and end with double underscores, often referred to as \u201cdunder\u201d methods.","breadcrumb":{"@id":"https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.w3computing.com\/articles\/write-custom-magic-methods-python-classes\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Articles Home","item":"https:\/\/www.w3computing.com\/articles\/"},{"@type":"ListItem","position":2,"name":"Programming Languages","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/"},{"@type":"ListItem","position":3,"name":"How to Write Custom Magic Methods for Python Classes"}]},{"@type":"WebSite","@id":"https:\/\/www.w3computing.com\/articles\/#website","url":"https:\/\/www.w3computing.com\/articles\/","name":"Developer Articles Hub","description":"","alternateName":"Developer Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.w3computing.com\/articles\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561","name":"w3compadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","url":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","contentUrl":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","caption":"w3compadmin"},"sameAs":["http:\/\/w3computing.com\/articles"]}]}},"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":"w3compadmin","author_link":"https:\/\/www.w3computing.com\/articles\/author\/w3compadmin\/"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/1741","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/comments?post=1741"}],"version-history":[{"count":7,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/1741\/revisions"}],"predecessor-version":[{"id":1748,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/1741\/revisions\/1748"}],"wp:attachment":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/media?parent=1741"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/categories?post=1741"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/tags?post=1741"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}