{"id":145,"date":"2024-01-25T13:44:05","date_gmt":"2024-01-25T13:44:05","guid":{"rendered":"https:\/\/learnpython.elegantwallp.com\/?p=145"},"modified":"2024-01-25T13:44:07","modified_gmt":"2024-01-25T13:44:07","slug":"python-private-attributes","status":"publish","type":"post","link":"https:\/\/learnpython.elegantwallp.com\/2024\/01\/25\/python-private-attributes\/","title":{"rendered":"Python Private Attributes"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you\u2019ll learn about encapsulation and how to use private attributes to accomplish encapsulation in Python.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction to encapsulation in Python<\/h2>\n\n\n\n<p>Encapsulation is one of the four fundamental concepts in object-oriented programming including abstraction, encapsulation, inheritance, and polymorphism.<\/p>\n\n\n\n<p>Encapsulation is the packing of data and\u00a0functions\u00a0that work on that data within a single object. By doing so, you can hide the internal state of the object from the outside. This is known as\u00a0<strong>information hiding<\/strong>.<\/p>\n\n\n\n<p>A\u00a0class\u00a0is an example of encapsulation. A class bundles data and methods into a single unit. And a class provides the access to its attributes via methods.<\/p>\n\n\n\n<p>The idea of information hiding is that if you have an attribute that isn\u2019t visible to the outside, you can control the access to its value to make sure your object is always has a valid state.<\/p>\n\n\n\n<p>Let\u2019s take a look at an example to better understand the encapsulation concept.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Python encapsulation example<\/h2>\n\n\n\n<p>The following defines the\u00a0<code>Counter<\/code>\u00a0class:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>class Counter: def __init__(self): self.current = 0 def increment(self): self.current += 1 def value(self): return self.current def reset(self): self.current = 0 <\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>The&nbsp;<code>Counter<\/code>&nbsp;class has one attribute called&nbsp;<code>current<\/code>&nbsp;which defaults to zero. And it has three methods:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>increment()<\/code>&nbsp;increases the value of the&nbsp;<code>current<\/code>&nbsp;attribute by one.<\/li>\n\n\n\n<li><code>value()<\/code>&nbsp;returns the current value of the&nbsp;<code>current<\/code>&nbsp;attribute<\/li>\n\n\n\n<li><code>reset()<\/code>&nbsp;sets the value of the&nbsp;<code>current<\/code>&nbsp;attribute to zero.<\/li>\n<\/ul>\n\n\n\n<p>The following creates a new instance of the\u00a0<code>Counter<\/code>\u00a0class and calls the\u00a0<code>increment()<\/code>\u00a0method three times before showing the current value of the counter to the screen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>counter = Counter() counter.increment() counter.increment() counter.increment() print(counter.value()) <\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Output:<code>3<\/code><small>Code language: Python (python)<\/small><\/p>\n\n\n\n<p>It works perfectly fine but has one issue.<\/p>\n\n\n\n<p>From the outside of the\u00a0<code>Counter<\/code>\u00a0class, you still can access the current attribute and change it to whatever you want. For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>counter = Counter() counter.increment() counter.increment() counter.current = -999 print(counter.value()) <\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>-999<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>In this example, we create an instance of the&nbsp;<code>Counter<\/code>&nbsp;class, call the&nbsp;<code>increment()<\/code>&nbsp;method twice and set the value of the current attribute to an invalid value&nbsp;<code>-999<\/code>.<\/p>\n\n\n\n<p>So how do you prevent the&nbsp;<code>current<\/code>&nbsp;attribute from modifying outside of the&nbsp;<code>Counter<\/code>&nbsp;class?<\/p>\n\n\n\n<p>That\u2019s why private attributes come into play.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Private attributes<\/h2>\n\n\n\n<p>Private attributes can be only accessible from the methods of the class. In other words, they cannot be accessible from outside of the class.<\/p>\n\n\n\n<p>Python doesn\u2019t have a concept of private attributes. In other words, all attributes are accessible from the outside of a class.<\/p>\n\n\n\n<p>By convention, you can define a private attribute by prefixing a single underscore (_):<code>_attribute<\/code><\/p>\n\n\n\n<p>This means that the _attribute should not be manipulated and may have a breaking change in the future.<\/p>\n\n\n\n<p>The following redefines the\u00a0<code>Counter<\/code>\u00a0class with the\u00a0<code>current<\/code>\u00a0as a private attribute by convention:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>class Counter: def __init__(self): self._current = 0 def increment(self): self._current += 1 def value(self): return self._current def reset(self): self._current = 0 <\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Name mangling with double underscores<\/h2>\n\n\n\n<p>If you prefix an attribute name with double underscores (<code>__<\/code>) like this:<code>__attribute<\/code><\/p>\n\n\n\n<p>Python will automatically change the name of the&nbsp;<code>__attribute<\/code>&nbsp;to:<code>_class__attribute<\/code><\/p>\n\n\n\n<p>This is called the name mangling in Python.<\/p>\n\n\n\n<p>By doing this, you cannot access the __attribute directly from the outside of a class like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>instance.__attribute<\/code><small>Code language: CSS (css)<\/small><\/code><\/pre>\n\n\n\n<p>However, you still can access it using the _class__attribute name:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>instance._class__attribute<\/code><small>Code language: CSS (css)<\/small><\/code><\/pre>\n\n\n\n<p>The following example redefines the Counter class with the __current attribute:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>class Counter: def __init__(self): self.__current = 0 def increment(self): self.__current += 1 def value(self): return self.__current def reset(self): self.__current = 0<\/code><\/code><\/pre>\n\n\n\n<p>Now, if you attempt to access __current attribute, you\u2019ll get an error:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>counter = Counter() print(counter.__current)<\/code><small>Code language: PHP (php)<\/small><\/code><\/pre>\n\n\n\n<p>Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>AttributeError: 'Counter' object has no attribute '__current'<\/code><small>Code language: JavaScript (javascript)<\/small><\/code><\/pre>\n\n\n\n<p>However, you can access the __current attribute as _Counter___current like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>counter = Counter() print(counter._Counter__current)<\/code><\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Summary: in this tutorial, you\u2019ll learn about encapsulation and how to use private attributes to accomplish encapsulation in Python. Introduction to encapsulation in Python Encapsulation is one of the four fundamental concepts in object-oriented programming including abstraction, encapsulation, inheritance, and polymorphism. Encapsulation is the packing of data and\u00a0functions\u00a0that work on that data within a single [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25],"tags":[],"class_list":["post-145","post","type-post","status-publish","format-standard","hentry","category-1-classes-and-objects"],"_links":{"self":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/145","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/comments?post=145"}],"version-history":[{"count":1,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/145\/revisions"}],"predecessor-version":[{"id":146,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/145\/revisions\/146"}],"wp:attachment":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/media?parent=145"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/categories?post=145"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/tags?post=145"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}