I’ve often had to deal with sensitive data that shouldn’t be touched by just any part of the code.
Whether I was building a payroll system for a firm in New York or a healthcare app in Chicago, keeping certain details “private” was always a priority.
In Python, we don’t have “private” keywords like Java or C++, but we have some very clever ways to achieve the same result.
In this tutorial, I will show you how I use private variables to implement data hiding in Python, using real-world examples you’d actually see in a professional environment.
What is Data Hiding in Python?
Data hiding is a technique used in Object-Oriented Programming (OOP) to restrict access to the internal details of a class.
It prevents the data from being modified accidentally, which can lead to bugs that are a nightmare to track down.
In Python, we use a convention of underscores to signal that a variable is intended for internal use only.
Method 1: Use a Single Underscore (Protected Variables)
During my early days as a developer, I learned that a single underscore before a variable name (like _salary) is a “gentleman’s agreement.”
It doesn’t actually stop anyone from accessing the variable, but it tells other developers, “Hey, please don’t touch this directly.”
Example: Employee Benefits Tracking
Imagine you are managing an employee database for a tech startup in San Francisco. You might want to protect the _health_plan_id.
class Employee:
def __init__(self, name, health_plan):
self.name = name
# Single underscore indicates a protected variable
self._health_plan_id = health_plan
def display_employee(self):
print(f"Employee Name: {self.name}")
print(f"Health Plan ID: {self._health_plan_id}")
# Creating an instance
emp = Employee("John Doe", "Aetna-9982")
# We can still access it, but we shouldn't
print(emp._health_plan_id) I executed the above example code and added the screenshot below.

I usually use this when I’m working in a team where everyone follows the PEP 8 style guide. It’s a way of staying organized without being too restrictive.
Method 2: Use Double Underscores (Private Variables and Name Mangling)
When I need to be more serious about data hiding, like when handling Social Security Numbers (SSN) or Credit Card details, I use double underscores (__).
This triggers something called Name Mangling. Python changes the name of the variable internally, so it can’t be accessed easily from outside the class.
Example: Secure Banking System in the USA
Let’s look at a banking example where we need to hide the account balance and the routing number.
class BankAccount:
def __init__(self, owner, initial_balance, routing_no):
self.owner = owner
# Double underscores make these private
self.__balance = initial_balance
self.__routing_number = routing_no
def deposit(self, amount):
if amount > 0:
self.__balance += amount
print(f"Deposited ${amount}. New balance: ${self.__balance}")
def get_balance(self):
# Controlled access via a method
return f"Current Balance: ${self.__balance}"
# Creating a bank account for a client in Texas
account = BankAccount("Sarah Jenkins", 5000, "123456789")
# Attempting to access private variable directly will raise an AttributeError
try:
print(account.__balance)
except AttributeError:
print("Error: Access Denied. The balance is private.")
# Correct way to access the data
print(account.get_balance())I executed the above example code and added the screenshot below.

In my experience, this is the closest Python gets to “True” private variables. If you try to access account.__balance, the code will crash.
However, if you really wanted to “break in,” you could use _BankAccount__balance. But in a professional setting, we never do that.
Method 3: Use Property Decorators for Controlled Access
Sometimes I want to hide the data but still allow people to see it or change it under specific conditions. This is where the @property decorator comes in.
This is my favorite method because it allows me to add validation logic, such as ensuring a ZIP code is exactly 5 digits.
Example: Real Estate Listing in Florida
Let’s say we are building a real estate app. We want to hide the __price but allow it to be updated only if the new price is a positive number.
class PropertyListing:
def __init__(self, address, price):
self.address = address
self.__price = price
@property
def price(self):
"""The getter method"""
return f"${self.__price:,}"
@price.setter
def price(self, new_price):
"""The setter method with validation"""
if new_price > 0:
self.__price = new_price
else:
print("Invalid Price! Please enter a positive value.")
# Listing a house in Miami
house = PropertyListing("123 Ocean Drive, Miami, FL", 850000)
# Accessing like a regular attribute thanks to @property
print(f"Address: {house.address}")
print(f"Price: {house.price}")
# Updating the price using the setter
house.price = 900000
print(f"Updated Price: {house.price}")
# Trying an invalid price
house.price = -100I executed the code above and added the screenshot below.

I find this method incredibly useful for maintaining data integrity. It keeps the internal variable hidden while providing a clean API for the user.
Why Should You Use Data Hiding?
Over the years, I’ve seen many projects fail because one part of the code changed a variable it wasn’t supposed to.
Data hiding provides several benefits:
- Security: It protects sensitive information from unauthorized access within the program.
- Flexibility: You can change the internal implementation of a class without breaking the code that uses it.
- Validation: It allows you to check if the data being assigned is valid (like checking a US phone number format).
- Reduced Complexity: It hides the “messy” parts of the logic from the user.
Private Variables vs. Protected Variables
In the Python world, the distinction is subtle but important.
- Internal Use (_var): Use this for variables that are intended for internal use but aren’t strictly “secret.”
- Private/Mangling (__var): Use this when you want to avoid name clashes in subclasses or when you really want to discourage direct access.
[Image comparing Protected vs Private variables in Python]
Common Issues to Avoid
When I first started using name mangling, I made the mistake of thinking it was a security feature. It is not.
Anyone who knows how Python works can still access your __variable if they try hard enough. Think of it as a “Keep Out” sign rather than a bank vault.
Also, don’t overuse private variables. If everything in your class is private, your code becomes very hard to test and debug. Use it only for data that truly needs protection.
I hope this tutorial helped you understand how to implement data hiding in your Python projects.
It’s a powerful tool that, when used correctly, makes your code much more robust and professional.
You may also like to read:
- Call Super Constructors with Arguments in Python
- Naming Conventions in Python
- Call a Base Class Constructor with Arguments in Python
- Check if an Object is Iterable in Python

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.