{"id":1089,"date":"2023-05-05T22:39:00","date_gmt":"2023-05-05T17:09:00","guid":{"rendered":"https:\/\/geekpython.in\/?p=1089"},"modified":"2023-08-15T13:23:48","modified_gmt":"2023-08-15T07:53:48","slug":"context-managers-and-python-with-statement","status":"publish","type":"post","link":"https:\/\/geekpython.in\/context-managers-and-python-with-statement","title":{"rendered":"Context Managers And The &#8216;with&#8217; Statement In Python: A Comprehensive Guide With Examples"},"content":{"rendered":"\n<p>In this article, we&#8217;ll look at context managers and how they can be used with Python&#8217;s &#8220;<code>with<\/code>&#8221; statements and how to create our own custom context manager.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"heading-what-is-context-manager\"><a href=\"https:\/\/geekpython.in\/context-managers-and-python-with-statement#heading-what-is-context-manager\"><\/a>What Is Context Manager?<\/h2>\n\n\n\n<p>Resource management is critical in any programming language, and the use of system resources in programs is common.<\/p>\n\n\n\n<p>Assume we are working on a project where we need to establish a database connection or perform file operations; these operations consume resources that are limited in supply, so they must be released after use; otherwise, issues such as running out of memory or file descriptors, or exceeding the maximum number of connections or network bandwidth can arise.<\/p>\n\n\n\n<p><strong>Context managers<\/strong>&nbsp;come to the rescue in these situations; they are used to prepare resources for use by the program and then free resources when the resources are no longer required, even if exceptions have occurred.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"heading-why-use-context-manager\"><a href=\"https:\/\/geekpython.in\/context-managers-and-python-with-statement#heading-why-use-context-manager\"><\/a>Why Use Context Manager?<\/h2>\n\n\n\n<p>As previously discussed, context managers provide a mechanism for the setup and teardown of the resources associated with the program. It improves the readability, conciseness, and maintainability of the code.<\/p>\n\n\n\n<p>Consider the following example, in which we perform a file writing operation without using the&nbsp;<code>with<\/code>&nbsp;statement.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># Opening file\nfile = open('sample.txt', 'w')\ntry:\n    # Writing data into file\n    data = file.write(\"Hello\")\nexcept Exception as e:\n    print(f\"Error Occurred: {e}\")\nfinally:\n    # Closing the file\n    file.close()<\/pre><\/div>\n\n\n\n<p>To begin, we had to write more lines of code in this approach, and we had to manually close the file in the&nbsp;<code>finally<\/code>&nbsp;block.<\/p>\n\n\n\n<p>Even if an exception occurs,&nbsp;<code>finally<\/code>&nbsp;block will ensure that the file is closed. However, using the&nbsp;<code>open()<\/code>&nbsp;function with the&nbsp;<code>with<\/code>&nbsp;statement reduces the excess code and eliminates the need to manually close the file.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">with open(\"sample.txt\", \"w\") as file:\n    data = file.write(\"Hello\")<\/pre><\/div>\n\n\n\n<p>In the preceding code, when the&nbsp;<code>with<\/code>&nbsp;statement is executed, the&nbsp;<code>open()<\/code>&nbsp;function&#8217;s&nbsp;<code>__enter__<\/code>&nbsp;method is called, which returns a file object. The file object is then assigned to the variable&nbsp;<code>file<\/code>&nbsp;by the&nbsp;<code>as<\/code>&nbsp;clause, and the content of the&nbsp;<code>sample.txt<\/code>&nbsp;file is written using the variable&nbsp;<code>file<\/code>. Finally, when the program exits execution, the&nbsp;<code>__exit__<\/code>&nbsp;method is invoked to close the file.<\/p>\n\n\n\n<p>We&#8217;ll learn more about&nbsp;<code>__enter__<\/code>&nbsp;and&nbsp;<code>__exit__<\/code>&nbsp;methods in the upcoming sections.<\/p>\n\n\n\n<p>We can check if the file is actually closed or not.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">print(file.closed)\n\n----------\nTrue<\/pre><\/div>\n\n\n\n<p>We received the result&nbsp;<code>True<\/code>, indicating that the file is automatically closed once the execution exits the&nbsp;<code>with<\/code>&nbsp;block.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"heading-using-with-statement\"><a href=\"https:\/\/geekpython.in\/context-managers-and-python-with-statement#heading-using-with-statement\"><\/a>Using with Statement<\/h2>\n\n\n\n<p>If you used the&nbsp;<code>with<\/code>&nbsp;statement, it is likely that you also used the context manager. The&nbsp;<code>with<\/code>&nbsp;statement is probably most commonly used when opening a file.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># Opening a file\nwith open('sample.txt', 'r') as file:\n    content = file.read()<\/pre><\/div>\n\n\n\n<p>Here&#8217;s a simple program that opens a text file and reads the content. When the&nbsp;<code>open()<\/code>&nbsp;function is evaluated after the&nbsp;<code>with<\/code>&nbsp;statement, context manager is obtained.<\/p>\n\n\n\n<p>The context manager implements two methods called&nbsp;<code>__enter__<\/code>&nbsp;and&nbsp;<code>__exit__<\/code>. The&nbsp;<code>__enter__<\/code>&nbsp;method is called at the start to prepare the resource to be used, and the&nbsp;<code>__exit__<\/code>&nbsp;method is called at the end to release resources.<\/p>\n\n\n\n<p>Python runs the above code in the following order:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The&nbsp;<code>with<\/code>&nbsp;statement is executed, and the&nbsp;<code>open()<\/code>&nbsp;function is called.<\/li>\n\n\n\n<li>The&nbsp;<code>open()<\/code>&nbsp;function&#8217;s&nbsp;<code>__enter__<\/code>&nbsp;method opens the file and returns the file object. The&nbsp;<code>as<\/code>&nbsp;clause then assigns the file object to the&nbsp;<code>file<\/code>&nbsp;variable.<\/li>\n\n\n\n<li>The inner block of the code&nbsp;<code>content = file.read()<\/code>&nbsp;gets executed.<\/li>\n\n\n\n<li>In the end, the&nbsp;<code>__exit__<\/code>&nbsp;method is called to perform the cleanup and closing of the file.<\/li>\n<\/ul>\n\n\n\n<p>Let&#8217;s define and implement both these methods in a Python class and try to understand the execution flow of the program.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"heading-creating-context-manager\"><a href=\"https:\/\/geekpython.in\/context-managers-and-python-with-statement#heading-creating-context-manager\"><\/a>Creating Context Manager<\/h2>\n\n\n\n<p>The context manager will be created by implementing the&nbsp;<code>__enter__<\/code>&nbsp;and&nbsp;<code>__exit__<\/code>&nbsp;methods within the class. Any class that has both of these methods can act as a context manager.<\/p>\n\n\n\n<p><strong>Defining a Python class<\/strong><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># Creating a class-based context manager\nclass Conmanager:\n    def __enter__(self):\n        print(\"Context Manager's enter method is called.\")\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        print(\"Exit method is called...\")\n        print(f'Exception Type: {exc_type}')\n        print(f'Exception Value: {exc_val}')\n        print(f'Exception Traceback: {exc_tb}')\n\n# Using the \"with\" stmt\nwith Conmanager() as cn:\n    print(\"Inner block of code within the 'with' statement.\")<\/pre><\/div>\n\n\n\n<p>First, we created a class named&nbsp;<code>Conmanager<\/code>&nbsp;and defined the&nbsp;<code>__enter__<\/code>&nbsp;and&nbsp;<code>__exit__<\/code>&nbsp;methods inside the class. Then we created the&nbsp;<code>Conmanager<\/code>&nbsp;object and assigned it to the variable&nbsp;<code>cn<\/code>&nbsp;using the&nbsp;<code>as<\/code>&nbsp;clause. We will get the following output after running the above program.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">Context Manager's enter method is called.\nInner block of code within the 'with' statement.\nExit method is called...\nException Type: None\nException Value: None\nException Traceback: None<\/pre><\/div>\n\n\n\n<p>When the&nbsp;<code>with<\/code>&nbsp;block is executed, Python orders the execution flow as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>As we can see from the output, the&nbsp;<code>__enter__<\/code>&nbsp;method is called first.<\/li>\n\n\n\n<li>The code contained within the&nbsp;<code>with<\/code>&nbsp;statement is executed.<\/li>\n\n\n\n<li>To exit the&nbsp;<code>with<\/code>&nbsp;statement block, the&nbsp;<code>__exit__<\/code>&nbsp;method is called at the end.<\/li>\n<\/ul>\n\n\n\n<p>We can see in the output that we got&nbsp;<code>None<\/code>&nbsp;values for the&nbsp;<code>exc_type<\/code>,&nbsp;<code>exc_val<\/code>, and&nbsp;<code>exc_tb<\/code>&nbsp;parameters passed inside the&nbsp;<code>__exit__<\/code>&nbsp;method of the class&nbsp;<code>Conmanager<\/code>.<\/p>\n\n\n\n<p>When an exception occurs while executing the&nbsp;<code>with<\/code>&nbsp;statement, these parameters take effect.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>exc_type<\/code>&nbsp;&#8211; displays the&nbsp;<strong>type of exception<\/strong>.<\/li>\n\n\n\n<li><code>exc_val<\/code>&nbsp;&#8211; displays the&nbsp;<strong>message of the exception<\/strong>.<\/li>\n\n\n\n<li><code>exc_tb<\/code>&nbsp;&#8211; displays the&nbsp;<strong>traceback object<\/strong>&nbsp;of the exception.<\/li>\n<\/ul>\n\n\n\n<p>Consider the following example, which shows how these parameters were used when an exception occurred.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># Creating a class-based context manager\nclass Conmanager:\n    def __enter__(self):\n        print(\"Enter method is called.\")\n\n        return \"Do some stuff\"\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        print(\"Exit method is called...\")\n        print(f'Exception Type: {exc_type}')\n        print(f'Exception Value: {exc_val}')\n        print(f'Exception Traceback: {exc_tb}')\n\n# Using the \"with\" stmt\nwith Conmanager() as cn:\n    print(cn)\n    # Raising exception on purpose\n    cn.read()<\/pre><\/div>\n\n\n\n<p>When we run the above code, we get the following result.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">Enter method is called.\nDo some stuff\nExit method is called...\nException Type: &lt;class 'AttributeError'&gt;\nException Value: 'str' object has no attribute 'read'\nException Traceback: &lt;traceback object at 0x00000276057D4800&gt;\nTraceback (most recent call last):\n  ....\n    cn.read()\nAttributeError: 'str' object has no attribute 'read'<\/pre><\/div>\n\n\n\n<p>Instead of getting&nbsp;<code>None<\/code>&nbsp;values, we got the&nbsp;<code>AttributeError<\/code>, as shown in the output above and those three parameters displayed certain values.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>exc_type<\/code>&nbsp;displayed the&nbsp;<code>&lt;class 'AttributeError'&gt;<\/code>&nbsp;value.<\/li>\n\n\n\n<li><code>exc_val<\/code>&nbsp;displayed the&nbsp;<code>'str' object has no attribute 'read'<\/code>&nbsp;message.<\/li>\n\n\n\n<li><code>exc_tb<\/code>&nbsp;displayed the&nbsp;<code>&lt;traceback object at 0x00000276057D4800&gt;<\/code>&nbsp;value.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"heading-example\"><a href=\"https:\/\/geekpython.in\/context-managers-and-python-with-statement#heading-example\"><\/a>Example<\/h2>\n\n\n\n<p>In the following example, we&#8217;ve created a context manager class that will reverse a sequence.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">class Reverse:\n    def __init__(self, data):\n        self.data = data\n\n    def __enter__(self):\n        self.operate = self.data[:: -1]\n        return self.operate\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        pass\n\n\nwith Reverse(\"Geek\") as rev:\n    print(f\"Reversed string: {rev}\")<\/pre><\/div>\n\n\n\n<p>We&#8217;ve created a class called&nbsp;<code>Reverse<\/code>&nbsp;and defined the&nbsp;<code>__init__<\/code>&nbsp;method, which takes&nbsp;<code>data<\/code>, the&nbsp;<code>__enter__<\/code>&nbsp;method, which operates on the&nbsp;<code>data<\/code>&nbsp;and returns the reversed version of it, and the&nbsp;<code>__exit__<\/code>&nbsp;method, which does nothing.<\/p>\n\n\n\n<p>Then we used the&nbsp;<code>with<\/code>&nbsp;statement to call the context manager&#8217;s object, passing the sequence&nbsp;<code>\"Geek\"<\/code>&nbsp;and assigning it to the&nbsp;<code>rev<\/code>&nbsp;using the&nbsp;<code>as<\/code>&nbsp;clause before printing it. We will get the following output after running the above code.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">Reversed string: keeG<\/pre><\/div>\n\n\n\n<p>The upper code contains a flaw because we did not include any exception-handling code within the&nbsp;<code>__exit__<\/code>&nbsp;method.&nbsp;<strong>What if we run into an exception?<\/strong><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">with Reverse(\"Geek\") as rev:\n    # Modified the code from here\n    print(rev.copy())<\/pre><\/div>\n\n\n\n<p>We changed the code within the&nbsp;<code>with<\/code>&nbsp;statement and attempted to print the&nbsp;<code>rev.copy()<\/code>. This will result in an error.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">Traceback (most recent call last):\n  ....\n    print(f\"Reversed string: {rev.copy()}\")\nAttributeError: 'str' object has no attribute 'copy'<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"heading-exception-handling\"><a href=\"https:\/\/geekpython.in\/context-managers-and-python-with-statement#heading-exception-handling\"><\/a>Exception Handling<\/h2>\n\n\n\n<p>Let&#8217;s include the exception handling code in the&nbsp;<code>__exit__<\/code>&nbsp;method.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">class Reverse:\n    def __init__(self, data):\n        self.data = data\n\n    def __enter__(self):\n        self.operate = self.data[:: -1]\n        return self.operate\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        if exc_type is None:\n            return self.operate\n        else:\n            print(f\"Exception occurred: {exc_type}\")\n            print(f\"Exception message: {exc_val}\")\n            return True\n\nwith Reverse(\"Geek\") as rev:\n    print(rev.copy())\n\nprint(\"Execution of the program continues...\")<\/pre><\/div>\n\n\n\n<p>First, we defined the condition to return the reversed sequence if the&nbsp;<code>exc_type<\/code>&nbsp;is&nbsp;<code>None<\/code>, otherwise, return the exception type and message in a nicely formatted manner.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">Exception occurred: &lt;class 'AttributeError'&gt;\nException message: 'str' object has no attribute 'copy'\nExecution of the program continues...<\/pre><\/div>\n\n\n\n<p>The exception was handled correctly by the&nbsp;<code>__exit__<\/code>&nbsp;method, and because we returned&nbsp;<code>True<\/code>&nbsp;when the error occurs, the program execution continues even after exiting the&nbsp;<code>with<\/code>&nbsp;statement block and we know because the&nbsp;<code>print<\/code>&nbsp;statement was executed which is written outside the&nbsp;<code>with<\/code>&nbsp;block.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"heading-conclusion\"><a href=\"https:\/\/geekpython.in\/context-managers-and-python-with-statement#heading-conclusion\"><\/a>Conclusion<\/h2>\n\n\n\n<p><strong>Context managers<\/strong>&nbsp;provide a way to manage resources efficiently like by preparing them to use and then releasing them after they are no longer needed. The context managers can be used with Python&#8217;s&nbsp;<code>with<\/code>&nbsp;statement to handle the&nbsp;<strong>setup<\/strong>&nbsp;and&nbsp;<strong>teardown<\/strong>&nbsp;of resources in the program.<\/p>\n\n\n\n<p>However, we can create our own custom context manager by implementing the&nbsp;<strong>enter(setup)<\/strong>&nbsp;logic and&nbsp;<strong>exit(teardown)<\/strong>&nbsp;logic within a Python class.<\/p>\n\n\n\n<p>In this article, we&#8217;ve learned:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What is context manager and why they are used<\/strong><\/li>\n\n\n\n<li><strong>Using context manager with the<\/strong>&nbsp;<code>with<\/code>&nbsp;<strong>statement<\/strong><\/li>\n\n\n\n<li><strong>Implementing context management protocol within a class<\/strong><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83c\udfc6<strong>Other articles you might be interested in if you liked this one<\/strong><\/p>\n\n\n\n<p>\u2705<a rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/abc-in-python\" target=\"_blank\">Understanding the basics of the abstract base class(ABC) in Python<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" href=\"https:\/\/geekpython.in\/implement-getitem-setitem-and-delitem-in-python\" rel=\"noreferrer noopener\">Implement __getitem__, __setitem__ and __delitem__ in Python class to get, set and delete items<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" href=\"https:\/\/geekpython.in\/tempfile-in-python\" rel=\"noreferrer noopener\">Generate and manipulate temporary files using tempfile in Python<\/a>.<\/p>\n\n\n\n<p>\u2705<a rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/match-case-in-python\" target=\"_blank\">Using match-case statements for pattern matching in Python<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" href=\"https:\/\/geekpython.in\/python-sort-vs-sorted\" rel=\"noreferrer noopener\">Comparing the sort() and sorted() function in Python<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" href=\"https:\/\/geekpython.in\/super-in-python\" rel=\"noreferrer noopener\">Using super() function to implement attributes and methods of the parent class within the child class<\/a>.<\/p>\n\n\n\n<p>\u2705<a rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/str-and-repr-in-python\" target=\"_blank\">Using str and repr to change the string representation of the objects in Python<\/a>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>That&#8217;s all for now<\/strong><\/p>\n\n\n\n<p><strong>KeepCoding\u270c\u270c<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we&#8217;ll look at context managers and how they can be used with Python&#8217;s &#8220;with&#8221; statements and how to create our own custom context manager. What Is Context Manager? Resource management is critical in any programming language, and the use of system resources in programs is common. Assume we are working on a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1091,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"0","ocean_second_sidebar":"0","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"0","ocean_custom_header_template":"0","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"0","ocean_menu_typo_font_family":"0","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"0","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"off","ocean_gallery_id":[],"footnotes":""},"categories":[2],"tags":[12,31],"class_list":["post-1089","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python","tag-python","tag-python3","entry","has-media"],"_links":{"self":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1089","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/comments?post=1089"}],"version-history":[{"count":4,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1089\/revisions"}],"predecessor-version":[{"id":1291,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1089\/revisions\/1291"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/media\/1091"}],"wp:attachment":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/media?parent=1089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/categories?post=1089"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/tags?post=1089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}