Making Sense of Encapsulation and Objects in Python

In OOP (object oriented programming), a program is built using objects. Objects are created from classes[link], which define what data an object can store and what actions it can perform.

This approach keeps related logic together. Data and the functions that operate on that data live in the same place. As a result, code becomes easier to read and easier to maintain.

Introducing Encapsulation

Encapsulation is one of the key concepts behind object-oriented programming.

It allows you to protect the internal state of an object by using a simple set of public methods and attributes that function like doors. Behind these doors, you’ll find private attributes and methods that manage how the data is modified and who has access to it.

Encapsulation reduces accidental changes and ensures consistent usage.

In Python, it’s a common practice to prefix attributes and methods with a single underscore to indicate that they are intended for internal use only.

This convention signifies that these attributes should not be directly accessed from the outside. Doing so would violate principles of encapsulation, potentially leading to bugs.

This is how you should handle names that are not part of your class, module, or package public API.

NOTE: A single underscore does not enforce access control. It is just a naming convention. A signal to the reader, not a lock. That means outside code can still access the attribute directly. 

A Simple Encapsulation Example

Here is a basic example using a class with internal data.

In line 4 self._balance is marked as internal using a single underscore.

in line 6 we create the deposit method. This method updates the account balance.

  • It takes an amount as input
  • It modifies _balance internally
  • Outside code does not change _balance directly

This is encapsulation in action. Changes happen through controlled methods.

In line 10, the get_balance method provides read access to the internal balance.

  • It allows the class to control how balance is shared
  • It returns the value safely
  • It prevents direct access to _balance

How the Convention Can Be Violated

Python follows a principle of trust. The language assumes that developers understand conventions and respect them. Instead of blocking access, Python relies on readability and discipline.

The underscore communicates intent:
“This attribute is internal. Use the provided methods.”

But trust could be violated.

Example of violating the convention:

This works. Python does not stop it.

You have directly changed _balance from outside the class, even though the underscore says you should not.

The consequences are logical. Python will not raise an error, but problems can still arise.

For example, if the class expects balance updates to go through deposit, then direct changes can skip important checks.

This leads to bugs that are hard to trace because the change happened outside the class logic.

Wrapping It Up

Encapsulation strengthens OOP by protecting internal data and dictating how objects are used.

Instead of letting outside code change values freely, you guide interaction through methods. This keeps objects predictable and easier to debug. Once understood, it becomes a reliable way to build programs that stay clear as they grow.

Although my blog doesn’t support comments, feel free to reply via email or X.