{"id":17338,"date":"2017-06-12T12:15:24","date_gmt":"2017-06-12T09:15:24","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=17338"},"modified":"2017-06-10T10:46:28","modified_gmt":"2017-06-10T07:46:28","slug":"using-new-python-instance-properties","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/","title":{"rendered":"Using the New Python Instance Properties"},"content":{"rendered":"<p>Last week, <a href=\"https:\/\/www.webcodegeeks.com\/python\/another-look-instance-level-properties-python\/\">I showed you my new implementation for instance-level properties in Python<\/a>. This week, we\u2019ll take another look at it by implementing a few Delegated Properties and helpers to make using them just a hair nicer.<\/p>\n<h2>Recreating Kotlin\u2019s Built-In Delegates<\/h2>\n<p>For inspiration of what Delegated Properties to create, we\u2019ll start by recreating the ones built into Kotlin, starting with <code>Lazy<\/code>.<\/p>\n<h3>Lazy<\/h3>\n<p>The <code>Lazy<\/code> Delegated Property allows you to initialize it with a function that takes no parameters and returns an object \u2013 preferably one that is relatively expensive to create. Then, the first time the property is retrieved, the object is created a stored, which subsequent lookups will use.<\/p>\n<p>To start us off, let\u2019s create an object that we can use as a flag to represent that the value isn\u2019t initialized yet (we could use <code>None<\/code>, but it\u2019s possible that the function could return <code>None<\/code>, and we\u2019d start having some difficulties).<\/p>\n<pre class=\"brush:php\">no_value = object()<\/pre>\n<p>Using that, here\u2019s <code>Lazy<\/code>:<\/p>\n<pre class=\"brush:php\">class Lazy(DelegatedProperty):\r\n    def __init__(self, initializer, *, readonly=False):\r\n        self.value = no_value\r\n        self.initialize = initializer\r\n        self._readonly = readonly\r\n \r\n    @classmethod\r\n    def readonly(cls, initializer):\r\n        return cls(intializer, readonly=True)\r\n \r\n    def get(self, instance, name):\r\n        if self.value is no_value:\r\n            self.value = self.initialize()\r\n            self.initialize = None  # release the reference to prevent memory leak\r\n        return self.value\r\n \r\n    def set(self, value, instance, name):\r\n        if self._readonly:\r\n            raise AttributeError()\r\n        else:\r\n            self.value = value\r\n            if self.initializer:  # if it's not cleaned up, clean it up\r\n                self.initializer = None<\/pre>\n<p>Note the optional read-only with the convenient <code>readonly()<\/code> class method. I\u2019m not sure what else to say about it. If you have any trouble understanding any of these, ask me about it in the comments.<\/p>\n<h3>LateInit<\/h3>\n<p>Next up is <code>LateInit<\/code>. This isn\u2019t quite as handy in Python as it is in Kotlin, since it is largely provided to allow for non-null properties in a class that implements the bean protocol. The problem is that the bean protocol requires a constructor that takes no arguments, where all the fields on the class are initialized to null. In Kotlin, you have null safety, and people like to mark their fields as non-nullable. So, in order to make the bean field non-nullable and yet have them start of null, Kotlin includes <code>lateinit<\/code>, which represents an uninitialized non-nullable field. If the field is accessed before it is ever set to something, then it triggers an exception. Technically, this isn\u2019t a Delegated Property in Kotlin; it\u2019s a language modifier, but it could be implemented as a Delegated Property.<\/p>\n<p>What use does it have in Python? Well, it\u2019s possible you might want to create a class where some or all of the attributes aren\u2019t initialized right away, \u2013 rather they\u2019re set later \u2013 but the class requires some or all of those attributes for certain actions. This way, instead of writing verifiers at the beginning of those actions to be certain that they were set, you simply access the attribute, and if it wasn\u2019t set, it\u2019ll raise an exception on its own.<\/p>\n<p>Here\u2019s what such a Delegated Property looks like:<\/p>\n<pre class=\"brush:php\">class LateInit(DelegatedProperty):\r\n    def __init__(self, value=no_value, *, readonly=False):\r\n        self.value = value\r\n        self._readonly = readonly\r\n \r\n    @classmethod\r\n    def readonly(cls, value=no_value):\r\n        return cls(value, readonly=True)\r\n \r\n    def get(self, instance, name):\r\n        if self.value is no_value:\r\n            raise AttributeError(f\"Attribute, {name}, not yet initialized\")\r\n        else:\r\n            return self.value\r\n \r\n    def set(self, value, instance, name):\r\n        if self._readonly and self.value is not no_value:  # the second part allows you to use set to initialize the value later, even if it's read-only\r\n            raise AttributeError()\r\n        else:\r\n            self.value = value<\/pre>\n<p>The constructor and <code>readonly()<\/code> class method include the ability to initialize the property immediately, even though that\u2019s not the typical case, but I like the idea of making it a little more flexible that way.<\/p>\n<h3>ByMap<\/h3>\n<p>Sometimes, you just want to take in a dictionary in the constructor and have attributes refer to that dictionary for their values. That\u2019s what this Delegated Property does for you. So, it would be used like this:<\/p>\n<pre class=\"brush:php\">class ByMapUser:\r\n    a = InstanceProperty(ByMap)\r\n    b = InstanceProperty(ByMap.readonly)\r\n \r\n    def __init__(self, dict_of_values):\r\n        # dict_of_values should have entries for 'a' and 'b', or else\r\n        # using either property could cause a KeyError, although setting\r\n        # before getting will add the entry to the dict if it wasn't\r\n        # already there\r\n        self.a.initialize(dict_of_values)\r\n        self.b.initialize(dict_of_values)<\/pre>\n<p>And here, <code>a<\/code> and <code>b<\/code> will read from and write to the provided dictionary instead of to the instance\u2019s <code>__dict__<\/code>.<\/p>\n<pre class=\"brush:php\">class ByMap(DelegatedProperty):\r\n    def __init__(self, mapping, *, readonly=False):\r\n        self.mapping = mapping\r\n        self._readonly = readonly\r\n \r\n    @classmethod\r\n    def readonly(cls, mapping):\r\n        cls(mapping, readonly=True)\r\n \r\n    def get(self, instance, name):\r\n        return self.mapping[name]\r\n \r\n    def set(self, value, instance, name):\r\n        if self._readonly:\r\n            raise AttributeError()\r\n        else: \r\n            self.mapping[name] = value<\/pre>\n<p>Here is where passing in <code>name<\/code> to <code>get()<\/code> and <code>set()<\/code> methods really comes in handy. Without the automatic calculating and passing of names, this would be more tedious to implement and use. The name would have to be taken in through the constructor, which means the user would have to provide it with initialize call. And that means that it would have to be updated by hand if they ever decide to change the name in a refactoring.<\/p>\n<h3>Observable<\/h3>\n<p>Kotlin also has the <code>Observable<\/code> Delegated Property, which I don\u2019t see as being all that useful, so I won\u2019t bother showing you that one.<\/p>\n<h2>Custom Delegated Property: <code>Validate<\/code><\/h2>\n<p>One of the biggest reasons we ever need properties is to ensure that what is provided is a valid value to be given. While using the built-in Python <code>property<\/code> isn\u2019t bad for this use case, it does still require the user to have to think about where to <i>actually<\/i> store the value, and it requires the verbosity of creating a method. But the biggest shortfall is when you need to reuse the logic of that property elsewhere. You could implement a full-blown descriptor for it, but that\u2019s also excessive. With <code>Validate<\/code>, all you really need to implement is the validation function and possibly a helper function for creating the specific validator.<br \/>\n<code>def positive_int(num):<br \/>\nreturn isinstance(num, int) and num &gt; 0<\/code><\/p>\n<p>def positive_int_property():<br \/>\nreturn InstanceProperty(Validate.using(positive_int))<\/p>\n<p>class Foo:<br \/>\nbar = positive_int_property()<\/p>\n<p>def __init__(self, num):<br \/>\nself.bar.initialize(num)<\/p>\n<p>See how you could just write a simple validator function and use that with <code>InstanceProperty(Validate.using(&lt;function&gt;))<\/code>? Pretty nice, right? Let\u2019s see what <code>Validate<\/code> looks like, shall we?<\/p>\n<pre class=\"brush:php\">class InvalidValueError(TypeError): pass\r\n \r\n \r\nclass Validate(DelegatedProperty):\r\n    def __init__(self, validator, value,  *, readonly=False):\r\n        self.validate = validator\r\n        if self.validate(value):\r\n            self.value = value\r\n        else:\r\n            raise InvalidValueError()\r\n        self._readonly = readonly\r\n \r\n    @classmethod\r\n    def using(cls, validator, *, readonly=False):\r\n        return lambda value: cls(validator, value, readonly=readonly)\r\n \r\n    @classmethod\r\n    def readonly_using(cls, validator):\r\n        return cls.using(validator, readonly=True)\r\n    \r\n    def get(self, *args):\r\n        return self.value\r\n \r\n    def set(self, value, instance, name):\r\n        if self._readonly:\r\n            raise AttributeError()\r\n        elif self.validate(value):\r\n            self.value = value\r\n        else:\r\n            Raise InvalidValueError(f\"{name}, {value}\")  # needs a better message, I know<\/pre>\n<p>We had to unfortunately use lambda to implement the class methods. It could have been done by returning an inner function as well, but the lack of need for a name makes that excessive.<\/p>\n<p>It also kind of sucks that we can\u2019t do a proper error message in <code>__init__()<\/code> because we don\u2019t have access to the name and instance. To get around this, I\u2019m passing those arguments in as named arguments in <code>initialize<\/code> in the final version on <a href=\"https:\/\/github.com\/sad2project\/descriptor-tools\">GitHub<\/a> (I wrote <code>Validate<\/code> for the first time after last week\u2019s article and didn\u2019t want to present any changes to last week\u2019s code here). The Delegated Properties that don\u2019t use them can just add <code>**kwargs<\/code> into their <code>__init__()<\/code> signature and ignore it.<\/p>\n<h2>Helpers<\/h2>\n<h3>Shortening <code>InstanceProperty<\/code><\/h3>\n<p>Always instantiating an <code>InstanceProperty<\/code> using that full name is tedious, and could potentially be enough to keep people from using it in the first place. So let\u2019s make a shorter-named function that delegates to it:<\/p>\n<pre class=\"brush:php\">def by(instantiator):\r\n    return InstanceProperty(instantiator)<\/pre>\n<p>I chose \u201cby\u201d as the name since it reflects the keyword used in Kotlin. You can use whatever name you want.<\/p>\n<p>Why don\u2019t I just rename <code>InstanceProperty<\/code> to something shorter? Because anything shorter would likely lose meaning, and we always want our names to have meaning.<\/p>\n<h3>Read Only Wrappers<\/h3>\n<p>I have a couple ideas for this, both of which aren\u2019t compatible with 100% of Delegated Properties. Both of these make it so we don\u2019t need to have a class method named \u201creadonly\u201d, and otherwise make implementing Delegated Properties easier.<\/p>\n<p>The first is just a convenience function:<\/p>\n<pre class=\"brush:php\">def readonly(instantiator):\r\n    return partial(instantiator, readonly=True)<\/pre>\n<p>Which can then be used like this:<\/p>\n<pre class=\"brush:php\">class Foo:\r\n    bar = by(readonly(LateInit))\r\n    \u2026<\/pre>\n<p>Seeing that Delegated Properties aren\u2019t required to have the <code>readonly<\/code> parameter, this isn\u2019t 100% compatible. The respective properties should document whether or not they work with this function or not. This applies to the next one as well.<\/p>\n<pre class=\" brush:php\">class ReadOnly(DelegatedProperty):\r\n    def __init__(self, delegate):\r\n        self.delegate = delegate\r\n \r\n    @classmethod\r\n    def of(cls, delegate):\r\n        return lambda *args, **kwargs: cls(delegate(*args, **kwargs))\r\n \r\n    def get(self, instance, name):\r\n        return self.delegate.get(instance, name)<\/pre>\n<p><code>Readonly<\/code> is used in the following way:<\/p>\n<pre class=\"brush:php\">class Foo:\r\n    bar = by(ReadOnly.of(LateInit))\r\n    ...<\/pre>\n<p>It\u2019s annoying that we had to return a function within a function again, but when <code>InstanceProperty<\/code> needs a function for instantiating a Delegated Property, there\u2019s not a whole lot of choice.<\/p>\n<h2>Outro<\/h2>\n<p>So that\u2019s everything. Again, this is all in a <a href=\"https:\/\/github.com\/sad2project\/descriptor-tools\">GitHub repo<\/a>, which turns out to be the same repo (descriptor-tools) I made for my book. The new code is added, but not all the tests and documentation are written for it yet. When that\u2019s done, I\u2019ll submit the rest to PyPI so you can easily install it with pip.<\/p>\n<p>Thanks for reading, and I\u2019ll see you next week with an article about the MVP pattern.<\/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\/2017\/06\/10\/using-the-new-python-instance-properties\/\">Using the New Python Instance Properties<\/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>Last week, I showed you my new implementation for instance-level properties in Python. This week, we\u2019ll take another look at it by implementing a few Delegated Properties and helpers to make using them just a hair nicer. Recreating Kotlin\u2019s Built-In Delegates For inspiration of what Delegated Properties to create, we\u2019ll start by recreating the ones &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-17338","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>Using the New Python Instance Properties - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"Last week, I showed you my new implementation for instance-level properties in Python. This week, we\u2019ll take another look at it by implementing a few\" \/>\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\/using-new-python-instance-properties\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using the New Python Instance Properties - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"Last week, I showed you my new implementation for instance-level properties in Python. This week, we\u2019ll take another look at it by implementing a few\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/\" \/>\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=\"2017-06-12T09:15:24+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=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/\"},\"author\":{\"name\":\"Jacob Zimmerman\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/f54a53cfb8523f4ef6012aa63f075c39\"},\"headline\":\"Using the New Python Instance Properties\",\"datePublished\":\"2017-06-12T09:15:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/\"},\"wordCount\":1228,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/#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\/using-new-python-instance-properties\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/\",\"name\":\"Using the New Python Instance Properties - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg\",\"datePublished\":\"2017-06-12T09:15:24+00:00\",\"description\":\"Last week, I showed you my new implementation for instance-level properties in Python. This week, we\u2019ll take another look at it by implementing a few\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/#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\/using-new-python-instance-properties\/#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\":\"Using the New Python Instance Properties\"}]},{\"@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":"Using the New Python Instance Properties - Web Code Geeks - 2026","description":"Last week, I showed you my new implementation for instance-level properties in Python. This week, we\u2019ll take another look at it by implementing a few","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\/using-new-python-instance-properties\/","og_locale":"en_US","og_type":"article","og_title":"Using the New Python Instance Properties - Web Code Geeks - 2026","og_description":"Last week, I showed you my new implementation for instance-level properties in Python. This week, we\u2019ll take another look at it by implementing a few","og_url":"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2017-06-12T09:15:24+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":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/"},"author":{"name":"Jacob Zimmerman","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/f54a53cfb8523f4ef6012aa63f075c39"},"headline":"Using the New Python Instance Properties","datePublished":"2017-06-12T09:15:24+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/"},"wordCount":1228,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/#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\/using-new-python-instance-properties\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/","url":"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/","name":"Using the New Python Instance Properties - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/11\/python-logo.jpg","datePublished":"2017-06-12T09:15:24+00:00","description":"Last week, I showed you my new implementation for instance-level properties in Python. This week, we\u2019ll take another look at it by implementing a few","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/python\/using-new-python-instance-properties\/#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\/using-new-python-instance-properties\/#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":"Using the New Python Instance Properties"}]},{"@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\/17338","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=17338"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/17338\/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=17338"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=17338"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=17338"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}