Python Private Attributes

Summary: in this tutorial, you’ll learn about the 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 functions that 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 information hiding.

A class is 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.

The idea of information hiding is that if you have an attribute that isn’t visible to outside, you can control the access to its value to make sure your object is always has a valid state.

Let’s take a look at an exampe to better understand the encapsulation concept.

Python encapsulation example

The following defines the Counter class:

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 language: Python (python)

The Counter class has one attribute called current which defaults to zero. And it has three methods:

  • increment() increases the value of the current attribute by one.
  • value() returns the current value of the current attribute
  • reset() sets the value of the current attribute to zero.

The following creates a new instance of the Counter class and calls the increment() method three times before showing the current value of the counter to the screen:

counter = Counter() counter.increment() counter.increment() counter.increment() print(counter.value())
Code language: Python (python)

Output:

3
Code language: Python (python)

It works perfectly fine but has one issue.

From the outside of the Counter class, you still can access the current attribute and change it to whatever you want. For example:

counter = Counter() counter.increment() counter.increment() counter.current = -999 print(counter.value())
Code language: Python (python)

Output:

-999
Code language: Python (python)

In this example, we create an instance of the Counter class, call the increment() method twice and set the value of the current attribute to an invalid value -999.

So how do you prevent the current attribute from modifying outside of the Counter class?

That’s why private attributes come into play.

Private attributes

Private attributes can be only accessible from the methods of the class. In other words, they cannot be accessible from outside of the class.

To make an attribute private, you prefix it with a double underscore (__). The following redefines the Counter class with the current as a private attribute:

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 language: Python (python)

The following creates a new instance of the Counter class and access the __current attribute:

counter = Counter() print(counter.__current)
Code language: Python (python)

Python issues the following error:

AttributeError: 'Counter' object has no attribute '__current'
Code language: Python (python)

As you can see, the Counter class now can protect its internal state from the outside.

How private attributes actually work in Python

When you prefix an attribute with a double underscore (__), Python internally masks that attribute by a new name:

_class___attribute
Code language: Python (python)

For example, you still can access the __current attribute outside of the Counter class as follows:

counter = Counter() counter.increment() print(counter._Counter__current)
Code language: Python (python)

Output:

1
Code language: Python (python)

So Python just makes it difficult to access private attributes. It doesn’t prevent you from accessing them. And this is by design.

Summary

  • Encapsulation is the packing of data and methods into a class so that you can hide the information and restrict access from outside.
  • Prefix an attribute with a double underscore (__) to make it private.
  • In Python, you can define private attributes by convention, not by rules.
Did you find this tutorial helpful ?