{"id":4918,"date":"2023-09-11T17:40:59","date_gmt":"2023-09-12T00:40:59","guid":{"rendered":"https:\/\/ioflood.com\/blog\/?p=4918"},"modified":"2024-02-09T18:46:23","modified_gmt":"2024-02-10T01:46:23","slug":"python-abstract-class","status":"publish","type":"post","link":"https:\/\/ioflood.com\/blog\/python-abstract-class\/","title":{"rendered":"Python Abstract Classes | Usage Guide (With Examples)"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"alignright size-full is-resized\"><img decoding=\"async\" src=\"https:\/\/ioflood.com\/blog\/wp-content\/uploads\/2023\/09\/Abstract-class-definitions-in-Python-abstract-shapes-conceptual-diagrams-logo-300x300.jpg\" alt=\"Abstract class definitions in Python abstract shapes conceptual diagrams logo\" width=\"300\" height=\"300\" title=\"\"><\/figure>\n<\/div>\n<p>Are you finding it challenging to understand abstract classes in Python? You&#8217;re not alone. Many developers grapple with this concept, but once mastered, it can significantly streamline your coding process.<\/p>\n<p>Think of abstract classes as blueprints for other classes, guiding the structure of derived classes. They are a powerful tool in the Python programmer&#8217;s arsenal, enabling you to write more efficient, readable, and maintainable code.<\/p>\n<p><strong>In this guide, we&#8217;ll walk you through the ins and outs of abstract classes in Python, from basic usage to advanced techniques.<\/strong> We&#8217;ll cover everything from creating an abstract class using the <code>abc<\/code> module, to more complex uses of abstract classes, and even alternative approaches.<\/p>\n<p>Let&#8217;s get started!<\/p>\n<h2>TL;DR: How Do I Create an Abstract Class in Python?<\/h2>\n<blockquote><p>\n  In Python, you can create an abstract class using the <code>abc<\/code> module. This module provides the infrastructure for defining abstract base classes (ABCs).\n<\/p><\/blockquote>\n<p>Here&#8217;s a simple example:<\/p>\n<pre><code class=\"language-python line-numbers\">from abc import ABC, abstractmethod\n\nclass AbstractClassExample(ABC):\n    @abstractmethod\n    def do_something(self):\n        pass\n<\/code><\/pre>\n<p>In this example, we import the <code>ABC<\/code> and <code>abstractmethod<\/code> from the <code>abc<\/code> module. We then define an abstract class <code>AbstractClassExample<\/code> using the <code>ABC<\/code> as the base class. The <code>abstractmethod<\/code> decorator is used to declare the method <code>do_something<\/code> as an abstract method. This means that any class that inherits from <code>AbstractClassExample<\/code> must provide an implementation of the <code>do_something<\/code> method.<\/p>\n<blockquote><p>\n  This is a basic way to create an abstract class in Python, but there&#8217;s much more to learn about using and understanding abstract classes. Continue reading for a more detailed understanding and advanced usage scenarios.\n<\/p><\/blockquote>\n<h2>Creating an Abstract Class in Python: The Basics<\/h2>\n<p>In Python, abstract classes are created using the <code>abc<\/code> module, which stands for Abstract Base Class. This module provides the necessary infrastructure for defining abstract base classes (ABCs) in Python. The key components of this module that we&#8217;ll use are the <code>ABC<\/code> class and the <code>abstractmethod<\/code> decorator.<\/p>\n<h3>Understanding the <code>abc<\/code> Module<\/h3>\n<p>The <code>abc<\/code> module provides the <code>ABC<\/code> class that we can use as a base class for creating abstract classes. Here&#8217;s a simple example:<\/p>\n<pre><code class=\"language-python line-numbers\">from abc import ABC\n\nclass MyAbstractClass(ABC):\n    pass\n<\/code><\/pre>\n<p>In this example, we&#8217;ve created a class <code>MyAbstractClass<\/code> that inherits from <code>ABC<\/code>. However, at this point, <code>MyAbstractClass<\/code> is not yet an abstract class because it doesn&#8217;t contain any abstract methods.<\/p>\n<h3>Using the <code>abstractmethod<\/code> Decorator<\/h3>\n<p>To create an abstract method, we use the <code>abstractmethod<\/code> decorator. An abstract method is a method declared in an abstract class but doesn&#8217;t contain any implementation. Subclasses of the abstract class are generally expected to provide an implementation for these methods. Here&#8217;s an example:<\/p>\n<pre><code class=\"language-python line-numbers\">from abc import ABC, abstractmethod\n\nclass MyAbstractClass(ABC):\n    @abstractmethod\n    def my_abstract_method(self):\n        pass\n<\/code><\/pre>\n<p>In this example, <code>my_abstract_method<\/code> is an abstract method. If we create a subclass of <code>MyAbstractClass<\/code> and try to create an instance without providing an implementation for <code>my_abstract_method<\/code>, Python will raise a <code>TypeError<\/code>.<\/p>\n<pre><code class=\"language-python line-numbers\">class MyConcreteClass(MyAbstractClass):\n    pass\n\n# This will raise a TypeError\ninstance = MyConcreteClass()\n\n# Output:\n# TypeError: Can't instantiate abstract class MyConcreteClass with abstract method my_abstract_method\n<\/code><\/pre>\n<h3>Advantages and Potential Pitfalls<\/h3>\n<p>Using abstract classes provides a clear structure for your code and makes it easier to work in a team setting. It ensures that certain methods must be implemented in any subclass, which can help prevent errors.<\/p>\n<p>However, it&#8217;s important to remember that Python&#8217;s <code>abc<\/code> module is not enforced at the language level but rather at the runtime level. This means that errors related to not implementing abstract methods in a subclass will only be caught at runtime, not during syntax checking or linting. Therefore, thorough testing is crucial when working with abstract classes in Python.<\/p>\n<h2>Advanced Abstract Classes: Beyond the Basics<\/h2>\n<p>After mastering the basics of abstract classes in Python, you may find yourself needing more advanced techniques. Abstract classes can be used in more complex scenarios like multiple inheritance and interface implementation. Let&#8217;s dive into these concepts.<\/p>\n<h3>Multiple Inheritance with Abstract Classes<\/h3>\n<p>Python supports multiple inheritance, a feature where a class can inherit from more than one base class. This includes abstract classes. Here&#8217;s an example:<\/p>\n<pre><code class=\"language-python line-numbers\">from abc import ABC, abstractmethod\n\nclass Base1(ABC):\n    @abstractmethod\n    def method_from_base1(self):\n        pass\n\nclass Base2(ABC):\n    @abstractmethod\n    def method_from_base2(self):\n        pass\n\nclass Derived(Base1, Base2):\n    def method_from_base1(self):\n        return 'method_from_base1 implementation'\n    def method_from_base2(self):\n        return 'method_from_base2 implementation'\n\n# Now we can create an instance of Derived\ninstance = Derived()\nprint(instance.method_from_base1())\nprint(instance.method_from_base2())\n\n# Output:\n# 'method_from_base1 implementation'\n# 'method_from_base2 implementation'\n<\/code><\/pre>\n<p>In this example, <code>Derived<\/code> is a subclass of both <code>Base1<\/code> and <code>Base2<\/code> and provides an implementation for the abstract methods from both base classes.<\/p>\n<h3>Implementing Interfaces with Abstract Classes<\/h3>\n<p>In Python, abstract classes can also be used to implement interfaces. An interface is a blueprint for a class, much like an abstract class, but it usually only contains method signatures and no implementation.<\/p>\n<p>Here&#8217;s an example of using an abstract class to define an interface:<\/p>\n<pre><code class=\"language-python line-numbers\">from abc import ABC, abstractmethod\n\nclass MyInterface(ABC):\n    @abstractmethod\n    def method1(self):\n        pass\n    @abstractmethod\n    def method2(self):\n        pass\n\nclass MyClass(MyInterface):\n    def method1(self):\n        return 'method1 implementation'\n    def method2(self):\n        return 'method2 implementation'\n\n# Now we can create an instance of MyClass\ninstance = MyClass()\nprint(instance.method1())\nprint(instance.method2())\n\n# Output:\n# 'method1 implementation'\n# 'method2 implementation'\n<\/code><\/pre>\n<p>In this example, <code>MyInterface<\/code> is an abstract class that serves as an interface. <code>MyClass<\/code> is a concrete class that provides an implementation for the methods defined in <code>MyInterface<\/code>.<\/p>\n<p>Using abstract classes for more complex scenarios like these can greatly enhance the structure and readability of your code. However, as with any powerful tool, it&#8217;s important to use these techniques judiciously and in the right context.<\/p>\n<h2>Exploring Alternatives: Metaclasses and Third-Party Libraries<\/h2>\n<p>While the <code>abc<\/code> module is a powerful tool for creating abstract classes in Python, there are other approaches you can use, such as metaclasses and third-party libraries like <code>zope.interface<\/code>. Let&#8217;s dive into these alternative methods.<\/p>\n<h3>Using Metaclasses to Create Abstract Classes<\/h3>\n<p>A metaclass in Python is a class of a class, or rather, a class that defines the behavior of other classes. You can use metaclasses to create abstract classes in Python. Here&#8217;s an example:<\/p>\n<pre><code class=\"language-python line-numbers\">class AbstractClassMeta(type):\n    def __init__(cls, name, bases, attrs):\n        if not cls.__abstractmethods__:\n            raise TypeError(\"Can't instantiate abstract class\")\n\nclass AbstractClass(metaclass=AbstractClassMeta):\n    @property\n    @abstractmethod\n    def my_abstract_method(self):\n        pass\n<\/code><\/pre>\n<p>In this example, <code>AbstractClassMeta<\/code> is a metaclass that raises a <code>TypeError<\/code> if the class it&#8217;s being applied to doesn&#8217;t have any abstract methods. <code>AbstractClass<\/code> uses <code>AbstractClassMeta<\/code> as its metaclass and defines an abstract method <code>my_abstract_method<\/code>.<\/p>\n<h3>Leveraging Third-Party Libraries: <code>zope.interface<\/code><\/h3>\n<p>The <code>zope.interface<\/code> library is a third-party library that provides a way to define interfaces and abstract classes in Python. Here&#8217;s an example:<\/p>\n<pre><code class=\"language-python line-numbers\">from zope.interface import Interface, implementer\n\nclass IMyInterface(Interface):\n    def my_abstract_method():\n        \"\"\"This is an abstract method\"\"\"\n\n@implementer(IMyInterface)\nclass MyClass:\n    def my_abstract_method(self):\n        return 'my_abstract_method implementation'\n\n# Now we can create an instance of MyClass\ninstance = MyClass()\nprint(instance.my_abstract_method())\n\n# Output:\n# 'my_abstract_method implementation'\n<\/code><\/pre>\n<p>In this example, <code>IMyInterface<\/code> is an interface that defines an abstract method <code>my_abstract_method<\/code>. <code>MyClass<\/code> provides an implementation for <code>my_abstract_method<\/code> and is declared to implement <code>IMyInterface<\/code> using the <code>@implementer<\/code> decorator.<\/p>\n<p>These alternative approaches to creating abstract classes in Python can provide additional flexibility and capabilities beyond what the <code>abc<\/code> module offers. However, they also come with their own trade-offs. Metaclasses can be complex and difficult to understand, while third-party libraries add external dependencies to your project. As always, it&#8217;s important to consider the specific needs and constraints of your project when deciding which approach to use.<\/p>\n<h2>Troubleshooting Abstract Classes: Common Errors and Solutions<\/h2>\n<p>Working with abstract classes in Python can sometimes lead to errors or obstacles. Let&#8217;s explore some common issues and their solutions.<\/p>\n<h3>Instantiating an Abstract Class<\/h3>\n<p>One common mistake when working with abstract classes is attempting to create an instance of an abstract class. Since abstract classes are meant to be a blueprint for other classes, they cannot be instantiated directly. Trying to do so will lead to a <code>TypeError<\/code>.<\/p>\n<pre><code class=\"language-python line-numbers\">from abc import ABC, abstractmethod\n\nclass MyAbstractClass(ABC):\n    @abstractmethod\n    def my_abstract_method(self):\n        pass\n\n# Trying to instantiate an abstract class\ninstance = MyAbstractClass()\n\n# Output:\n# TypeError: Can't instantiate abstract class MyAbstractClass with abstract method my_abstract_method\n<\/code><\/pre>\n<p>The solution is to create a concrete subclass that implements all the abstract methods of the abstract class, and then instantiate that subclass.<\/p>\n<h3>Not Implementing All Abstract Methods<\/h3>\n<p>Another common error is not implementing all the abstract methods in a subclass of an abstract class. If a subclass doesn&#8217;t provide implementations for all abstract methods of the superclass, Python will raise a <code>TypeError<\/code> when you try to create an instance of the subclass.<\/p>\n<pre><code class=\"language-python line-numbers\">from abc import ABC, abstractmethod\n\nclass MyAbstractClass(ABC):\n    @abstractmethod\n    def my_abstract_method(self):\n        pass\n\nclass MyConcreteClass(MyAbstractClass):\n    pass\n\n# Trying to instantiate a subclass that doesn't implement all abstract methods\ninstance = MyConcreteClass()\n\n# Output:\n# TypeError: Can't instantiate abstract class MyConcreteClass with abstract method my_abstract_method\n<\/code><\/pre>\n<p>The solution is to ensure that all subclasses implement all abstract methods of the superclass.<\/p>\n<h2>Best Practices and Optimization<\/h2>\n<p>When working with abstract classes in Python, it&#8217;s important to follow best practices to ensure your code is efficient and maintainable. Here are a few tips:<\/p>\n<ul>\n<li>Use abstract classes when you want to provide a common interface for different classes.<\/li>\n<li>Don&#8217;t overuse abstract classes. If a class doesn&#8217;t need to provide an interface and doesn&#8217;t have any abstract methods, it probably doesn&#8217;t need to be an abstract class.<\/li>\n<li>Keep abstract classes small and focused. They should define a specific interface, not try to do too many things at once.<\/li>\n<li>Remember that Python&#8217;s <code>abc<\/code> module is a runtime feature. Errors related to abstract classes won&#8217;t be caught until your code is actually running, so make sure to thoroughly test any code that uses abstract classes.<\/li>\n<\/ul>\n<h2>Python Abstract Classes: An OOP Perspective<\/h2>\n<p>To fully understand the concept of abstract classes in Python, it&#8217;s crucial to have a grasp of some fundamental principles of Object-Oriented Programming (OOP). These principles include inheritance, encapsulation, and polymorphism. Let&#8217;s examine these concepts and the role of abstract classes in each.<\/p>\n<h3>Inheritance: The Parent-Child Relationship<\/h3>\n<p>Inheritance is an OOP principle that allows one class to inherit the properties and methods of another class. In the context of abstract classes, the abstract class serves as the parent class, and the subclasses that implement the abstract methods are the child classes.<\/p>\n<pre><code class=\"language-python line-numbers\">from abc import ABC, abstractmethod\n\nclass Parent(ABC):\n    @abstractmethod\n    def common_method(self):\n        pass\n\nclass Child(Parent):\n    def common_method(self):\n        return 'Implemented in Child class'\n\nchild = Child()\nprint(child.common_method())\n\n# Output:\n# 'Implemented in Child class'\n<\/code><\/pre>\n<p>In this example, <code>Parent<\/code> is an abstract class with an abstract method <code>common_method<\/code>. <code>Child<\/code> is a subclass of <code>Parent<\/code> that provides an implementation for <code>common_method<\/code>.<\/p>\n<h3>Encapsulation: Hiding the Complexity<\/h3>\n<p>Encapsulation is the principle of hiding the internal workings of an object and exposing only what is necessary. Abstract classes play a role in encapsulation by defining a clear interface that other classes can implement, hiding the complexity of the underlying implementation.<\/p>\n<h3>Polymorphism: One Interface, Many Implementations<\/h3>\n<p>Polymorphism is the ability of an object to take on many forms. With abstract classes, polymorphism is achieved through the implementation of the abstract methods in the subclasses. Each subclass can provide a different implementation, allowing for a variety of behaviors.<\/p>\n<pre><code class=\"language-python line-numbers\">from abc import ABC, abstractmethod\n\nclass AbstractAnimal(ABC):\n    @abstractmethod\n    def make_sound(self):\n        pass\n\nclass Dog(AbstractAnimal):\n    def make_sound(self):\n        return 'Woof!'\n\nclass Cat(AbstractAnimal):\n    def make_sound(self):\n        return 'Meow!'\n\ndog = Dog()\ncat = Cat()\nprint(dog.make_sound())\nprint(cat.make_sound())\n\n# Output:\n# 'Woof!'\n# 'Meow!'\n<\/code><\/pre>\n<p>In this example, <code>Dog<\/code> and <code>Cat<\/code> are subclasses of the abstract class <code>AbstractAnimal<\/code> and provide different implementations for the <code>make_sound<\/code> method, demonstrating polymorphism.<\/p>\n<p>In conclusion, abstract classes in Python play a crucial role in implementing the principles of OOP. They provide a blueprint for creating subclasses, encapsulate complexity, and enable polymorphism, making your code more structured, maintainable, and flexible.<\/p>\n<h2>Abstract Classes in the Wild: Real-World Applications<\/h2>\n<p>Abstract classes are not just theoretical constructs, but they have practical applications in larger projects and real-world scenarios. They are often used in software design patterns, such as the Template Method pattern, where an abstract class defines a &#8216;skeleton&#8217; of an algorithm in an operation and defers some steps to subclasses.<\/p>\n<pre><code class=\"language-python line-numbers\">from abc import ABC, abstractmethod\n\nclass AbstractClass(ABC):\n    def template_method(self):\n        self.primitive_operation1()\n        self.primitive_operation2()\n\n    @abstractmethod\n    def primitive_operation1(self):\n        pass\n\n    @abstractmethod\n    def primitive_operation2(self):\n        pass\n\nclass ConcreteClass(AbstractClass):\n    def primitive_operation1(self):\n        print('Primitive operation 1 implementation')\n\n    def primitive_operation2(self):\n        print('Primitive operation 2 implementation')\n\nconcrete = ConcreteClass()\nconcrete.template_method()\n\n# Output:\n# 'Primitive operation 1 implementation'\n# 'Primitive operation 2 implementation'\n<\/code><\/pre>\n<p>In this example, <code>AbstractClass<\/code> defines the <code>template_method<\/code> which outlines the algorithm&#8217;s structure and calls <code>primitive_operation1<\/code> and <code>primitive_operation2<\/code>, which are abstract methods. The <code>ConcreteClass<\/code> provides the specific implementations for these operations.<\/p>\n<h3>Related Topics: Exploring Further<\/h3>\n<p>As you continue to explore abstract classes, you&#8217;ll likely encounter related topics such as mixins, interfaces, and software design patterns. These concepts often accompany abstract classes in typical use cases and provide additional tools for structuring and organizing your code.<\/p>\n<h3>Further Resources for Mastering Python Abstract Classes<\/h3>\n<p>To deepen your understanding of abstract classes and related topics, here are some resources that offer more in-depth information:<\/p>\n<ul>\n<li><a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/ioflood.com\/blog\/python-oop-object-oriented-programming\/\">Python OOP Best Practices<\/a> &#8211; Dive into inheritance in Python to build relationships between classes and reuse code.<\/p>\n<\/li>\n<li>\n<p><a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/ioflood.com\/blog\/python-object\/\">Exploring the Object Class in Python<\/a> &#8211; Learn about Python objects as instances of classes, representing real-world entities.<\/p>\n<\/li>\n<li>\n<p><a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/ioflood.com\/blog\/python-class\/\">Understanding Classes in Python<\/a> &#8211; Learn how to define and instantiate classes in Python for object-oriented programming.<\/p>\n<\/li>\n<li>\n<p><a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/docs.python.org\/3\/library\/abc.html\" target=\"_blank\" rel=\"noopener\">Python&#8217;s Official Documentation on the ABC Module<\/a> &#8211; Learn about Python&#8217;s abstract base class module from official sources.<\/p>\n<\/li>\n<li>\n<p>Real Python&#8217;s <a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/realpython.com\/inheritance-composition-python\/\" target=\"_blank\" rel=\"noopener\">Guide on Abstract Base Classes<\/a> &#8211; Detailed explanation of abstract base classes in Python.<\/p>\n<\/li>\n<li>\n<p>Python-Course&#8217;s <a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/www.python-course.eu\/python3_abstract_classes.php\" target=\"_blank\" rel=\"noopener\">Tutorial on Abstract Classes<\/a> &#8211; Step-by-step guide to understanding abstract classes in Python.<\/p>\n<\/li>\n<\/ul>\n<p>These resources provide a wealth of information and examples that can help you master the use of abstract classes in Python and apply them effectively in your own projects.<\/p>\n<h2>Wrapping Up: Mastering Python Abstract Classes<\/h2>\n<p>In this comprehensive guide, we&#8217;ve navigated through the concept of abstract classes in Python. From understanding the basic use to exploring advanced techniques, we&#8217;ve covered the essential aspects of this powerful programming construct.<\/p>\n<p>We started with the basics, learning how to create an abstract class using the <code>abc<\/code> module. We then ventured into more advanced territory, discussing complex uses such as multiple inheritance and interface implementation.<\/p>\n<p>Along the way, we tackled common challenges you might face when using abstract classes and provided solutions to help you overcome these hurdles.<\/p>\n<p>We also looked at alternative approaches to creating abstract classes, such as using metaclasses and third-party libraries like <code>zope.interface<\/code>. This gave us a broader understanding of the various ways to implement abstract classes in Python.<\/p>\n<p>Here&#8217;s a quick comparison of these methods:<\/p>\n<table>\n<thead>\n<tr>\n<th>Method<\/th>\n<th>Flexibility<\/th>\n<th>Complexity<\/th>\n<th>External Dependencies<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>abc module<\/td>\n<td>Moderate<\/td>\n<td>Low<\/td>\n<td>None<\/td>\n<\/tr>\n<tr>\n<td>Metaclasses<\/td>\n<td>High<\/td>\n<td>High<\/td>\n<td>None<\/td>\n<\/tr>\n<tr>\n<td>zope.interface<\/td>\n<td>Moderate<\/td>\n<td>Moderate<\/td>\n<td>Yes<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Whether you&#8217;re a beginner just starting out with abstract classes or an experienced Python developer looking to level up your skills, we hope this guide has given you a deeper understanding of abstract classes in Python and how to use them effectively in your code. Happy coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Are you finding it challenging to understand abstract classes in Python? You&#8217;re not alone. Many developers grapple with this concept, but once mastered, it can significantly streamline your coding process. Think of abstract classes as blueprints for other classes, guiding the structure of derived classes. They are a powerful tool in the Python programmer&#8217;s arsenal, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":10699,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[121,123],"tags":[],"class_list":["post-4918","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming-coding","category-python","cat-121-id","cat-123-id","has_thumb"],"_links":{"self":[{"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/posts\/4918","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/comments?post=4918"}],"version-history":[{"count":6,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/posts\/4918\/revisions"}],"predecessor-version":[{"id":17257,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/posts\/4918\/revisions\/17257"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/media\/10699"}],"wp:attachment":[{"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/media?parent=4918"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/categories?post=4918"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/tags?post=4918"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}