What is encapsulation in Python?

“Encapsulation is not a matter of whether you use an object or not, it’s a matter of how well you hide the details.” — Bjarne Stroustrup (Creator of C++)

The process of wrapping up variables and methods into a single entity is known as Encapsulation. It is one of the underlying concepts in object-oriented programming (OOP). Encapsulation in Python acts as a protective shield that puts restrictions on accessing variables and methods directly, and can prevent accidental or unauthorized modification of data. Encapsulation also makes objects into more autonomous, independently functioning pieces.

Moreover, encapsulation is not only about hiding details but also about controlling access and safeguarding an object’s internal state.

Encapsulation
Encapsulation

Why encapsulation is required in Python

Encapsulation is vital in Python programming because it helps you write well-organized, readable code. It ensures that the inner workings of your classes remain hidden from the outside world, making your application more secure and easier to maintain.

For Python software engineers, encapsulation ensures simplicity, flexibility, and efficiency.

How we can achieve encapsulation in Python

Python uses access modifiers to limit access to class variables and methods. Let’s dive into the three access levels in Python:

  • Public

  • Protected

  • Private

Let's see how the above-mentioned access modifiers help achieve encapsulation in Python.

Public members

Public members are accessible anywhere from the class. All the member variables of the class are, by default, public.

# Program to illustrate public access modifier in a class
class edpresso:
# Constructor
def __init__(self, name, project):
self.name = name;
self.project = project;
def displayProject(self):
# Accessing public data member
print("Project: ", self.project)
# Creating object of the class
edp = edpresso("TeamPhoenix", 1);
# Accessing public data member
print("Name: ", edp.name)
# Calling public member function of the class
edp.displayProject()

In the above edpresso class, the variable name and project are public. These data members can be accessed anywhere in the program.

Protected members

Protected members are accessible within the class and are also available to its sub-classes. To define a protected member, prefix the member name with a single underscore (_).

# Program to illustrate protected access modifier in a class
class edpresso:
def __init__(self, name, project):
self._name = name
self._project = project
# Creating object of the class
edp = edpresso("TeamPhoenix", 2)
# Direct access of protected member
print("Name:",edp._name)
print("project:",edp._project)

In the above code, the variable name and project of class edpresso are protected; hence, it is accessed as _name, and _project, respectively.

Try this: Modify the public member after creating the object and observe how the encapsulation works in different scenarios.

Private members

Private members are accessible within the class. To define a private member, prefix the member name with a double underscore (__).

# Program to illustrate private access modifier in a class
class edpresso:
def __init__(self, name, project):
# Public variable
self.name = name
# Private variable
self.__project = project
# Creating an instance of the class Sample
edp = edpresso('TeamPhoenix', 3)
# Accessing public variable name
print("Name:",edp.name)
# Accessing private variable __project using
# _Edpresso__project name
print("Project:",edp._edpresso__project)

In class edpresso, __project is a private variable; hence, it is accessed by creating an instance.

Note: Python’s private and protected members can be accessed outside the class through Python name mangling. This method gives private members a name with two leading underscores and no more than one trailing underscore.

For example, __box will be mangled, as ___box ,__box_, but __box__ and __box___ will not.

Let’s see another example where we try to directly access a private member:

class MyClass:
def __init__(self, name):
self.__name = name
obj = MyClass('Encapsulation')
print(obj.__name)

The above code will raise an error 'MyClass' object has no attribute' because we directly tried to access the private member.

Benefits of encapsulation

Encapsulation in Python offers several advantages, from enhanced code readability to better data protection.

  • Aesthetics: Encapsulation makes the application appealing and more comfortable to understand.
  • Authority: Encapsulation protects an object from unauthorized access. It allows access to a level without revealing the intricate details below that level.
  • Simplicity: It simplifies the maintenance of the application and reduces human errors. In larger codebases, encapsulation simplifies debugging and maintenance by isolating the internal workings of classes. This prevents external interference and ensures that changes made to the class’s internal logic do not disrupt other parts of the program. As a result, it reduces the chances of human errors.

Encapsulation offers several practical benefits as well, particularly in larger software projects. By restricting direct access to an object’s internal data and controlling how it’s modified through methods, encapsulation enhances data security and integrity. This prevents unintended or harmful interactions between components, making the system more robust. It also improves code maintainability by keeping internal implementation details hidden, allowing developers to change internal logic without affecting other parts of the application. In larger projects, this leads to cleaner, modular code that’s easier to manage, debug, and scale over time.

Best practices

Following these encapsulation best practices ensures your code remains clean, maintainable, and secure.

  • Use protected or private members wisely: Only use protected (_attribute) or private (__attribute) members when necessary. This signals to other developers that these members are not intended for external access or modification.

  • Avoid overusing getters and setters: Use getter and setter methods only when needed (e.g., when controlling how a value is accessed or modified). Overuse can make your code unnecessarily complex, especially for large classes. Let’s understand this with the help of an example:

# Unnecessary getter and setter approach
class MyClassWithGetSet:
def __init__(self, value):
self._value = value
def get_value(self):
return self._value
def set_value(self, value):
self._value = value
# A cleaner Pythonic approach using @property
class MyClassWithProperty:
def __init__(self, value):
self._value = value
@property
def value(self):
return self._value
# Class with getter and setter methods
obj_getset = MyClassWithGetSet(10)
print("Initial value (get/set):", obj_getset.get_value())
obj_getset.set_value(20)
print("Updated value (get/set):", obj_getset.get_value())
# Class with @property decorator
obj_property = MyClassWithProperty(10)
print("Initial value (@property):", obj_property.value)
# obj_property.value = 20

Uncommenting line 30 will raise an AttributeError because there’s no setter.

The @property decorator provides a read-only attribute because no setter is defined. When you try to assign a new value to value (i.e., obj_property.value = 20), Python raises an AttributeError since the attribute is intended to be read-only.

  • Prioritize clarity: While encapsulation hides internal details, don’t obscure important information. The goal is to protect data without making your code hard to understand or maintain.

  • Use read-only properties when necessary: If an attribute should be accessible but not modifiable, use the @property decorator without a setter. This creates read-only properties that maintain encapsulation.

class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
c = Circle(5)
print(c.radius)
c.radius = 10

If we uncomment line 11, it will give AttributeError: can't set attribute error because there’s no setter method defined.

  • Remember, encapsulation is a convention: Python doesn’t enforce encapsulation. Use it as a guideline to make your code more secure and maintainable, but understand that developers can still access private members if they choose.

Key takeaways

  • Encapsulation is a fundamental concept in object-oriented programming (OOP) that binds together data and functions and restricts access to certain details of an object.

  • By default, encapsulation in Python is achieved through public, protected, and private access modifiers, which control the level of accessibility to class attributes and methods.

  • Using encapsulation prevents external modification of sensitive data, improving both security and code maintainability, and ensuring that the internal state of an object is only modified in controlled ways.

  • Encapsulation provides clear, structured, and self-sufficient classes that enhance the organization and scalability of a project while promoting better debugging and readability.

Become a Python developer with our comprehensive learning path!

Ready to kickstart your career as a Python Developer? Our “Become a Python Developer” path is designed to take you from your first line of code to landing your first job.


This comprehensive journey offers essential knowledge, hands-on practice, interview preparation, and a mock interview, ensuring you gain practical, real-world coding skills. With our AI mentor by your side, you’ll overcome challenges with personalized support, building the confidence needed to excel in the tech industry.

Frequently asked questions

Haven’t found what you were looking for? Contact Us


Why is encapsulation important in Python?

Encapsulation is important because it improves code security and maintainability. By controlling access to class attributes and methods, encapsulation helps prevent unauthorized access, reduces complexity, and makes code easier to maintain.


What is the difference between encapsulation and abstraction in Python?

Encapsulation focuses on restricting access to certain class components to protect the integrity of the data, while abstraction is about hiding the complexity of the system by exposing only essential details and hiding the implementation.


Is encapsulation enforced in Python?

Encapsulation in Python is more of a convention than a strict enforcement. Unlike other languages, Python doesn’t strictly prevent access to private or protected members, but using underscores signals to developers that certain attributes or methods are intended for internal use only.


What are the 4 pillars of Python?

When creating objects using classes, there are 4 basic principles for writing clean and concise code. These principles are called the four pillars of object-oriented programming (OOP). The pillars are inheritance, polymorphism, encapsulation, and abstraction.


What are the common mistakes that developers make when implementing encapsulation in Python?

A common mistake that developers make when implementing encapsulation in Python is not properly using access modifiers (like private or protected attributes) or overusing getters and setters, leading to unnecessary complexity and reduced readability.


Free Resources