{"id":14423,"date":"2016-08-18T12:15:26","date_gmt":"2016-08-18T09:15:26","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=14423"},"modified":"2016-08-15T22:27:46","modified_gmt":"2016-08-15T19:27:46","slug":"instance-level-properties-python","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/","title":{"rendered":"Instance-Level Properties in Python"},"content":{"rendered":"<p>Making Descriptors that act as specialized properties can be tricky, especially when it comes to storing the data the property controls. I should know, <a href=\"https:\/\/programmingideaswithjake.wordpress.com\/python-descriptors-book\/\">I literally wrote the book<\/a>. Looking at how other languages do it \u2013 especially Kotlin\u2019s Delegated Properties \u2013 I felt that Python could use a system that works more like that.<\/p>\n<p>Delegated Properties are simply objects stored on an instance that are accessed differently. When accessing the attribute on the instance, instead of returning the object stored there, it calls the object\u2019s getter or setter, depending on how it\u2019s being accessed.<\/p>\n<p>When designing properties for instances (think read-only attributes or properties that validate incoming data) as opposed to class-level descriptors (think classmethod or staticmethod), using regular descriptors can be a pain, since storing the value that they use is tricky. Storing it safely on the descriptor itself requires specialized storage (to avoid running into memory leaks or unhashable keys) whereas storing it on the instance itself requires avoiding using an attribute name that the instance already uses. The instance-level properties I will show you today allows you to avoid all of that.<\/p>\n<h2><b>Requirements<\/b><\/h2>\n<p>Before I show you what I made, I will guide you through some of the thought process.<\/p>\n<p>What do we require the system to do?<\/p>\n<ul>\n<li>We need to be able to store an object (which will be the property) under an attribute\u2019s name that will not be returned, but rather have its getter\/setter\/deleter used.<\/li>\n<li>We need a simple and preferably quick way to determine if an object is a property.<\/li>\n<li>We need to not be required to implement all of the getter, setter, and deleter methods unless they\u2019re useful<\/li>\n<\/ul>\n<h2><b>And How<\/b><\/h2>\n<p>So, to accomplish the first goal, we will need to override the <code>__getattribute__()<\/code>, <code>__setattr__()<\/code>, and <code>__delattr__()<\/code> methods of a class to 1) check that an attribute is actually property object and 2) if it is, call the appropriate method. Also, to accomplish the last point, we should catch <code>AttributeError<\/code>s that may be thrown if the method is unimplemented. I\u2019ve also decided that when these <code>AttributeError<\/code>s are caught, we will raise a new <code>AttributeError<\/code> that has a message along the lines of \u201cThis property does not support such and such action\u201d.<\/p>\n<p>In order to not have to implement this every time, we\u2019ll create a \u201cmixin\u201d base class that already does it, called `WithObjectProperties`:<\/p>\n<pre class=\"brush:php\">class WithObjectProperties(object):\r\n\r\n\r\n    def __getattribute__(self, key):\r\n        attr = super().__getattribute__(key)\r\n        if isObjectProperty(attr):\r\n            try:\r\n                return attr.get(???)\r\n            except AttrbuteError:\r\n                raise AttributeError(\"Property '{}' on object {j} does not allow read access\".format(key, self))\r\n        else:\r\n            return attr\r\n\r\n\r\n     def __setattr__(self, key, value):\r\n        try:\r\n            attr = super().__getattribute__(key)\r\n       except AttributeError:\r\n            attr = None\r\n\r\n        if isObjectProperty(attr):\r\n            try:\r\n                attr.set(???)\r\n            except AttributeError:\r\n                raise AttributeError(\"Property '{}' on object {} does not allow write access\".format(key, self))\r\n        else:\r\n            super().__setattr__(key, value)\r\n\r\n    def __delattr__(self, key):\r\n        attr = super().__getattribute__(key)\r\n        if isObjectProperty(attr):\r\n            try:\r\n                attr.delete(???)\r\n            except AttributeError:\r\n                raise AttributeError(\"Property '{}' on object {} does not allow deletion\".format(key, self))\r\n        super().__delattr__(key)<\/pre>\n<p>The one thing else that needs to be noted is that <code>__delattr__()<\/code> is designed in that it will actually remove the attribute if the calling the deleter method doesn\u2019t raise an <code>AttributeError<\/code>. So, if the property is designed to take care of deletion without itself actually being deleted, it should raise an <code>AttributeError<\/code> after doing what it does.<\/p>\n<p>Okay, so we still need to address the second point. In the previous code example, it called <code>isObjectProperty()<\/code>, but we haven\u2019t seen how that\u2019s implemented yet. After a bit of thinking, I decided to make it so that all object properties would have a boolean flag called <code><\/code>. If the flag exists and is <code>True<\/code>, then it\u2019s a object property. Otherwise, it\u2019s not.<\/p>\n<pre class=\"brush:php\">def isObjectProperty(obj):\r\n    try:\r\n        if obj._objprop:\r\n            return True\r\n        else:\r\n            return False\r\n    except AttributeError:\r\n        return False<\/pre>\n<p>So, this allows an object property class to define the attribute at its level if it never changes (the typical use case), but it also allows for some objects to decide at runtime whether it\u2019s an object property, and it can even change if it needs to. This allows a little more flexibility into the system, though admittedly, it\u2019s not likely to be used much or maybe not even at all. I don\u2019t really mind; it makes it so that it doesn\u2019t need to do up to three checks for whether any of the getter, setter, or deleter methods exist. It\u2019s quick and simple, so I\u2019m sticking with it. If you want to reimplement how the check works, that\u2019s completely fine.<\/p>\n<p>Next, we need to determine the parameters for the getter, setter, and deleter methods. Obviously, they\u2019ll have the <code>self<\/code> parameter (unless you implement them as class or static methods). Other than that, the setter method is the only one that <i>needs<\/i> a parameter, that being the new value to set to. I took a tip from normal descriptors and decided to include a parameter for the instance that the value is being held for, called <code>inst<\/code> \u2013 short for \u2018instance\u2019. One last parameter I decided to include because of my work with the descriptors book: the <code>name<\/code> of the attribute on the instance. This allows the property to store the actual attribute back onto the instance using a modified name (usually by adding an underscore to the beginning). Also, the inclusion of the instance and the name allows for well written error messages if something goes wrong.<\/p>\n<p>So that means that the three potential methods that an object property can have are:<\/p>\n<pre class=\"brush:php\">get(self, inst, name)\r\nset(self, inst, name, value)\r\ndelete(self, inst, name)<\/pre>\n<p>So, in the above code, the <code>???<\/code> spots should be changed to, in order, <code>self, key<\/code>, <code>self, key, value<\/code>, and <code>self, key<\/code>. These all happen to be the same set of parameters coming in to the surrounding method.<\/p>\n<p>If we are to make a base class for object properties to optionally derive from, It would be super simple and look like this:<\/p>\n<pre class=\"brush:php\">class ObjectProperty:\r\n    _objprop = True<\/pre>\n<p>We could potentially write some sort of ABC that checks that at least one of the methods are implemented, but that\u2019s kind of a waste of time.<\/p>\n<h2><b>Example!<\/b><\/h2>\n<p>So let\u2019s look at an example, shall we?<\/p>\n<p>Here\u2019s an object property that makes the attribute that it represents read-only:<\/p>\n<pre class=\"brush:php\">class ReadOnly(ObjectProperty):\r\n    def __init__(self, attr):\r\n        self.attr = attr\r\n\r\n    def get(self, inst, name):\r\n        return self.attr\r\nAnd an example of class using it:<\/pre>\n<pre class=\"brush:php\">class C(WithObjectProperties):\r\n    def __init__(self, a):\r\n        self.a = ReadOnly(a)<\/pre>\n<p>That\u2019s all! The class simply needs to derive from <code>WithObjectProperties<\/code> and assign an attribute with the desired object property. Here\u2019s what it\u2019s like to use this:<\/p>\n<pre class=\"brush:php\">&gt;&gt;&gt; c = C(5)\r\n&gt;&gt;&gt; c.a\r\n5\r\n&gt;&gt;&gt; c.a = 6\r\n\u2026\r\nAttributeError: Property 'a' on object &lt;C \u2026&gt; does not allow write access\r\n&gt;&gt;&gt; del c.a\r\n\u2026\r\nAttributeError: Property 'a' on object &lt;C \u2026&gt; does not allow deletion<\/pre>\n<p>Just accomplishing this goes a fair way towards making immutability easier in Python (though it\u2019s still not actually immutable, since you can get direct access to the property object via the instance\u2019s <code>__dict__<\/code>.<\/p>\n<h2><b>Interesting Side Note<\/b><\/h2>\n<p>One interesting tid bit here is that if we make <code>ReadOnly<\/code> inherit from <code>WithObjectProperties<\/code>, it can suddenly be a wrapper that turns other object properties into read-only versions of themselves.<\/p>\n<p>And I love me some wrapper action.<\/p>\n<h2><b>Outro<\/b><\/h2>\n<p>So, yeah, I\u2019ve gone and created instance-level properties. If this gets enough recognition, I may actually put up a library for it on GitHub and PyPI. Let me know what you think? Am I the only one who cares about this?\u00a0I know that it\u2019s entirely possible.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"https:\/\/programmingideaswithjake.wordpress.com\/2016\/08\/13\/instance-level-properties-in-python\/\">Instance-Level Properties in Python<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\">WCG partner<\/a> Jacob Zimmerman at the <a href=\"http:\/\/programmingideaswithjake.wordpress.com\/\">Programming Ideas With Jake<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Making Descriptors that act as specialized properties can be tricky, especially when it comes to storing the data the property controls. I should know, I literally wrote the book. Looking at how other languages do it \u2013 especially Kotlin\u2019s Delegated Properties \u2013 I felt that Python could use a system that works more like that. &hellip;<\/p>\n","protected":false},"author":51,"featured_media":1651,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[53],"tags":[],"class_list":["post-14423","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Instance-Level Properties in Python - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"Making Descriptors that act as specialized properties can be tricky, especially when it comes to storing the data the property controls. I should know, I\" \/>\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.webcodegeeks.com\/python\/instance-level-properties-python\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Instance-Level Properties in Python - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"Making Descriptors that act as specialized properties can be tricky, especially when it comes to storing the data the property controls. I should know, I\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2016-08-18T09:15:26+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Jacob Zimmerman\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/jacobz_20\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jacob Zimmerman\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/\"},\"author\":{\"name\":\"Jacob Zimmerman\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/f54a53cfb8523f4ef6012aa63f075c39\"},\"headline\":\"Instance-Level Properties in Python\",\"datePublished\":\"2016-08-18T09:15:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/\"},\"wordCount\":1075,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"articleSection\":[\"Python\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/\",\"name\":\"Instance-Level Properties in Python - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"datePublished\":\"2016-08-18T09:15:26+00:00\",\"description\":\"Making Descriptors that act as specialized properties can be tricky, especially when it comes to storing the data the property controls. I should know, I\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Python\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/python\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Instance-Level Properties in Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/f54a53cfb8523f4ef6012aa63f075c39\",\"name\":\"Jacob Zimmerman\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/2dfdd9e2d35ed2224faf73968f8c597b5489fc345287e06e2571d3935a6bcc86?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/2dfdd9e2d35ed2224faf73968f8c597b5489fc345287e06e2571d3935a6bcc86?s=96&d=mm&r=g\",\"caption\":\"Jacob Zimmerman\"},\"description\":\"Jacob is a certified Java programmer (level 1) and Python enthusiast. He loves to solve large problems with programming and considers himself pretty good at design.\",\"sameAs\":[\"https:\/\/programmingideaswithjake.wordpress.com\/\",\"https:\/\/x.com\/https:\/\/twitter.com\/jacobz_20\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/jacob-zimmerman\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Instance-Level Properties in Python - Web Code Geeks - 2026","description":"Making Descriptors that act as specialized properties can be tricky, especially when it comes to storing the data the property controls. I should know, I","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.webcodegeeks.com\/python\/instance-level-properties-python\/","og_locale":"en_US","og_type":"article","og_title":"Instance-Level Properties in Python - Web Code Geeks - 2026","og_description":"Making Descriptors that act as specialized properties can be tricky, especially when it comes to storing the data the property controls. I should know, I","og_url":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2016-08-18T09:15:26+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","type":"image\/jpeg"}],"author":"Jacob Zimmerman","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/jacobz_20","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Jacob Zimmerman","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/"},"author":{"name":"Jacob Zimmerman","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/f54a53cfb8523f4ef6012aa63f075c39"},"headline":"Instance-Level Properties in Python","datePublished":"2016-08-18T09:15:26+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/"},"wordCount":1075,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","articleSection":["Python"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/","url":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/","name":"Instance-Level Properties in Python - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","datePublished":"2016-08-18T09:15:26+00:00","description":"Making Descriptors that act as specialized properties can be tricky, especially when it comes to storing the data the property controls. I should know, I","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/python\/instance-level-properties-python\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Python","item":"https:\/\/www.webcodegeeks.com\/category\/python\/"},{"@type":"ListItem","position":3,"name":"Instance-Level Properties in Python"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/f54a53cfb8523f4ef6012aa63f075c39","name":"Jacob Zimmerman","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/2dfdd9e2d35ed2224faf73968f8c597b5489fc345287e06e2571d3935a6bcc86?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/2dfdd9e2d35ed2224faf73968f8c597b5489fc345287e06e2571d3935a6bcc86?s=96&d=mm&r=g","caption":"Jacob Zimmerman"},"description":"Jacob is a certified Java programmer (level 1) and Python enthusiast. He loves to solve large problems with programming and considers himself pretty good at design.","sameAs":["https:\/\/programmingideaswithjake.wordpress.com\/","https:\/\/x.com\/https:\/\/twitter.com\/jacobz_20"],"url":"https:\/\/www.webcodegeeks.com\/author\/jacob-zimmerman\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/14423","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/51"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=14423"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/14423\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/1651"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=14423"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=14423"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=14423"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}