codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🐍

Python Programming

35 / 68 topics
30Python OOP Concepts31Python Classes & Objects32Python Class Methods & Properties33Python Inheritance & Multiple Inheritance34Python Polymorphism & Operator Overloading35Python Encapsulation
Tutorials/Python Programming/Python Encapsulation
🐍Python Programming

Python Encapsulation

Updated 2026-05-15
30 min read

Python Encapsulation

Encapsulation is a fundamental concept in object-oriented programming (OOP) that involves bundling the data (attributes) and methods (functions) that operate on the data into a single unit or class. It also restricts direct access to some of an object's components, which can prevent the accidental modification of data. This tutorial will cover how to use public, protected, and private access modifiers in Python, including name mangling and using properties for controlled access.

Introduction

Encapsulation is crucial because it helps maintain the integrity of your code by preventing unintended changes to the internal state of an object. By controlling access to attributes and methods, you can ensure that objects are used correctly and that their behavior remains consistent. This makes your code more robust and easier to manage.

In Python, encapsulation is achieved through naming conventions for class members:

  • Public: Members are accessible from anywhere.
  • Protected: Members are intended to be accessed within the class and by subclasses (indicated by a single underscore prefix).
  • Private: Members are intended to be used only within the class itself (indicated by a double underscore prefix).

Public Attributes

Public attributes can be accessed from any part of your program. They do not have any special naming convention.

public_example.py
1class Car:
2 def __init__(self, make, model):
3 self.make = make # public attribute
4 self.model = model # public attribute
5
6 def display_info(self):
7 print(f"Car: {self.make} {self.model}")
8
9# Creating an instance of the Car class
10my_car = Car("Toyota", "Corolla")
11my_car.display_info()
Output
Car: Toyota Corolla

Protected Attributes

Protected attributes are indicated by a single underscore prefix. They should not be accessed from outside the class or its subclasses, although Python does not enforce this strictly.

protected_example.py
1class Car:
2 def __init__(self, make, model):
3 self._make = make # protected attribute
4 self._model = model # protected attribute
5
6 def display_info(self):
7 print(f"Car: {_make} {_model}")
8
9# Creating an instance of the Car class
10my_car = Car("Toyota", "Corolla")
11print(my_car._make) # Accessing a protected attribute (not recommended)
Output
Car: Toyota Corolla
Toyota

Tip

While Python does not enforce access restrictions for protected members, it is a convention to treat them as non-public and only use them within the class or its subclasses.

Private Attributes

Private attributes are indicated by a double underscore prefix. They are intended to be used only within the class itself. Python uses name mangling to make these attributes harder to access from outside the class.

private_example.py
1class Car:
2 def __init__(self, make, model):
3 self.__make = make # private attribute
4 self.__model = model # private attribute
5
6 def display_info(self):
7 print(f"Car: {self.__make} {self.__model}")
8
9# Creating an instance of the Car class
10my_car = Car("Toyota", "Corolla")
11my_car.display_info()
12# print(my_car.__make) # This will raise an AttributeError
Output
Car: Toyota Corolla
AttributeError: 'Car' object has no attribute '__make'

Warning

Accessing private attributes directly from outside the class is generally discouraged and can lead to unexpected behavior.

Name Mangling

Python automatically renames private attributes by adding an underscore followed by the class name to the beginning of the attribute name. This makes it harder to access these attributes from outside the class.

name_mangling_example.py
1class Car:
2 def __init__(self, make, model):
3 self.__make = make
4 self.__model = model
5
6# Creating an instance of the Car class
7my_car = Car("Toyota", "Corolla")
8print(my_car._Car__make) # Accessing a private attribute using name mangling (not recommended)
Output
Toyota

Note

Name mangling is not meant to be used as a security feature. It is simply a convention to indicate that an attribute should not be accessed from outside the class.

Using Properties for Controlled Access

Properties provide a way to control access to attributes by defining getter, setter, and deleter methods.

properties_example.py
1class Car:
2 def __init__(self, make, model):
3 self._make = make
4 self._model = model
5
6 @property
7 def make(self):
8 return self._make
9
10 @make.setter
11 def make(self, value):
12 if isinstance(value, str) and value.isalpha():
13 self._make = value
14 else:
15 raise ValueError("Make must be a string containing only alphabetic characters.")
16
17 @property
18 def model(self):
19 return self._model
20
21 @model.setter
22 def model(self, value):
23 if isinstance(value, str):
24 self._model = value
25 else:
26 raise ValueError("Model must be a string.")
27
28# Creating an instance of the Car class
29my_car = Car("Toyota", "Corolla")
30print(my_car.make) # Accessing using property getter
31
32my_car.make = "Honda" # Setting using property setter
33print(my_car.make)
34
35# my_car.make = 12345 # This will raise a ValueError
Output
Toyota
Honda
ValueError: Make must be a string containing only alphabetic characters.

Tip

Using properties allows you to add validation and other logic when getting or setting attribute values, making your code more robust.

Practical Example

Let's create a practical example that combines encapsulation concepts. We'll define a BankAccount class with private attributes for the account balance and methods to deposit, withdraw, and display the balance.

bank_account_example.py
1class BankAccount:
2 def __init__(self, owner, initial_balance=0):
3 self._owner = owner
4 self.__balance = initial_balance
5
6 @property
7 def balance(self):
8 return self.__balance
9
10 def deposit(self, amount):
11 if amount > 0:
12 self.__balance += amount
13 print(f"Deposited ${amount}. New balance: ${self.__balance}")
14 else:
15 raise ValueError("Deposit amount must be positive.")
16
17 def withdraw(self, amount):
18 if 0 < amount <= self.__balance:
19 self.__balance -= amount
20 print(f"Withdrew ${amount}. Remaining balance: ${self.__balance}")
21 else:
22 raise ValueError("Invalid withdrawal amount.")
23
24# Creating an instance of the BankAccount class
25account = BankAccount("Alice", 100)
26print(account.balance) # Accessing using property getter
27
28account.deposit(50)
29account.withdraw(30)
30
31# account.__balance = -100 # This will raise an AttributeError
Output
100
Deposited $50. New balance: $150
Withdrew $30. Remaining balance: $120
AttributeError: 'BankAccount' object has no attribute '__balance'

Summary

ConceptDescription
PublicAccessible from anywhere.
ProtectedIntended to be accessed within the class and subclasses (single underscore).
PrivateIntended to be used only within the class itself (double underscore).
Name ManglingPython renames private attributes to make them harder to access externally.
PropertiesControl access to attributes with getter, setter, and deleter methods.

What's Next?

Now that you have a solid understanding of encapsulation in Python, the next topic will cover list comprehensions. List comprehensions provide a concise way to create lists based on existing lists. This powerful feature is essential for writing clean and efficient code. Stay tuned!


PreviousPython Polymorphism & Operator OverloadingNext List Comprehensions

Recommended Gear

Python Polymorphism & Operator OverloadingList Comprehensions