View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All

Encapsulation in Python

Updated on 22/01/20258,049 Views

Encapsulation in Python refers to the concept of bundling data (attributes) and methods (functions) that operate on the data into a single unit, typically a class. It also controls access to the data by restricting direct access from outside the class. This allows for better data protection and prevents unintended modification.

Many developers struggle to understand how to effectively manage and protect data in a class while making the necessary functionality accessible. Without proper encapsulation, maintaining large codebases can become difficult.

In this guide, we’ll explore encapsulation in Python example and break down the types of encapsulation in Python. 

By the end, you'll be able to write cleaner, more maintainable code. 

“Enhance your Python skills further with our Data Science and Machine Learning courses from top universities — take the next step in your learning journey!”

Why Do We Need Encapsulation in Python?

Encapsulation in Python is the practice of bundling the data (attributes) and methods (functions) that operate on the data into a single unit called a class. 

It allows you to restrict direct access to some of the object’s components, which helps protect the integrity of the data.

For example, imagine a bank account. The balance in your account should only be changed by specific actions, such as deposits or withdrawals, not directly by anyone accessing the balance. By encapsulating the balance inside the class and providing controlled access through methods (deposit, withdraw), you ensure that the balance cannot be tampered with directly.

Why is encapsulation important?

1. Data Protection

Encapsulation helps protect the integrity of the data by restricting access.

For example, a user shouldn't be able to directly modify a critical attribute like an account balance without going through the correct validation checks (e.g., only allowing withdrawals if the balance is sufficient).

2. Simplifies Maintenance

Encapsulation hides the internal details of a class. If you decide to change how a method works (like changing how a calculation is done), you can do so without affecting other parts of your program that rely on the class. 

This makes maintaining and updating the code much easier.

3. Improved Code Readability

Encapsulation helps make code more readable and logical by organizing related data and methods within a class. 

When data and methods that act on the data are bundled together, it’s clearer what a particular part of the code is meant to do.

4. Controlled Access

Using encapsulation, you can define different levels of access to the data. 

For example, you can use public methods to allow safe interaction with data, while keeping internal implementation details private

“Start your coding journey with our complimentary Python courses designed just for you — dive into Python programming fundamentals, explore key Python libraries, and engage with practical case studies!”

Also Read: Object-Oriented Programming Concept in Python

Access Modifiers in Python Encapsulation

In Python, access modifiers control the visibility and accessibility of attributes and methods within a class. By using access modifiers, you can restrict access to certain parts of your code and ensure data integrity. 

There are three main types of access modifiers in Python: public, protected, and private.

1. Public Access

Public attributes and methods are accessible from anywhere, both inside and outside the class. These are the default type of attributes and methods if no access modifier is specified.

Example:You can create a public method or attribute by simply defining it without any prefix: 

class Employee:
    def __init__(self, name, salary):
        self.name = name  # Public attribute
        self.salary = salary  # Public attribute
    def display_info(self):  # Public method
        print(f"Employee Name: {self.name}, Salary: {self.salary}")

Explanation:

  • The name and salary attributes are public and can be accessed or modified from outside the class.
  • The display_info() method is also public and can be called directly from outside the class.

2. Protected Access

Protected attributes and methods are intended for internal use within the class and its subclasses. These members are prefixed with a single underscore _. 

While they can still be accessed from outside the class, it is a convention to treat them as protected, meaning they should not be modified directly.

Example:

class Employee:
    def __init__(self, name, salary):
        self._name = name  # Protected attribute
        self._salary = salary  # Protected attribute
    def _display_info(self):  # Protected method
        print(f"Employee Name: {self._name}, Salary: {self._salary}")

Explanation:

  • The _name and _salary attributes are protected, and while they can be accessed outside the class, it's best to avoid it.
  • The _display_info() method is also protected, meaning it should be used inside the class or by subclasses.

3. Private Access

Private attributes and methods are meant to be used only within the class they are defined in. They are prefixed with two underscores __, and Python internally changes their names (name mangling) to avoid accidental access or modification. 

Private members cannot be accessed directly from outside the class.

Example

class Employee:
    def __init__(self, name, salary):
        self.__name = name  # Private attribute
        self.__salary = salary  # Private attribute
    def __display_info(self):  # Private method
        print(f"Employee Name: {self.__name}, Salary: {self.__salary}")

Explanation:

  • The __name and __salary attributes are private and cannot be accessed directly from outside the class.
  • The __display_info() method is private, and attempting to call it directly from outside the class will result in an error.

Why Use Access Modifiers in Python?

  • By restricting access to certain attributes and methods, you protect your data from unintended changes.
  • Aaccess modifiers helps in keeping the class clean and organized, clearly distinguishing between what is meant for internal use and what is exposed to the outside world.
  • Access modifiers are an essential part of encapsulation. They provide the mechanism to hide or protect the internal state of an object and control how it interacts with the outside environment.

Key Takeaways:

  • Public members are accessible everywhere.
  • Protected members should not be accessed directly, though they can be.
  • Private members are hidden and can only be used within the class.

Also Read: Encapsulation in Java with Example

Encapsulation in Python Using Public Members

One of the easiest ways to understand encapsulation is by using public members, where both attributes and methods are openly accessible from outside the class.

This encapsulation in Python Example with public members is straightforward. Since public members don’t have any restrictions on access, anyone can interact with the class directly. 

Let’s take a look at an example:

class Car:
    def __init__(self, make, model, year):
        self.make = make  # Public attribute
        self.model = model  # Public attribute
        self.year = year  # Public attribute
    def display_info(self):  # Public method
        print(f"Car Make: {self.make}, Model: {self.model}, Year: {self.year}")
# Creating an instance of the Car class
car1 = Car("Toyota", "Corolla", 2020)
# Accessing public attributes directly
print(car1.make)  print(car1.year)  
# Calling the public method
car1.display_info()  

Output

Toyota
2020
Car Make: Toyota, Model: Corolla, Year: 2020

Explanation:

  • The class Car has three public attributes: make, model, and year. Since these attributes are public, they can be accessed directly from outside the class, like car1.make.
  • The method display_info() is also public. This allows the user to display the car's information from outside the class.

Why Use Public Encapsulation?

  • Public members are easily accessible and allow for quick interaction with data and methods.
  • Public attributes and methods simplify the design and implementation, especially for small-scale projects or when you want to implement features that don't require strict data validation quickly.

Things to Keep in Mind:

While public members allow flexibility, they also expose the internal details of your class. This means that any part of your code can directly modify your data, which could lead to unintended consequences if not managed properly.

For larger projects, types of encapsulation in Python that offer more controlled access (like protected or private) are often better suited for data integrity. 

Public members are typically used in simpler or smaller-scale applications where such strict data control isn’t necessary.

Encapsulation in Python Using Private Members

In Python, private members y are prefixed with double underscores (__), signaling that they should not be accessed directly by external code. 

The private members can only be accessed or modified using methods defined within the class, or through controlled access provided by getter or setter methods.

Here’s an example:

class BankAccount:
    def __init__(self, account_holder, balance):
        self.account_holder = account_holder  # Public attribute
        self.__balance = balance  # Private attribute
    def deposit(self, amount):
        """Method to deposit money to the account."""
        if amount > 0:
            self.__balance += amount  # Modifying the private attribute
        else:
            print("Amount should be positive.")
    def withdraw(self, amount):
        """Method to withdraw money from the account."""
        if 0 < amount <= self.__balance:
            self.__balance -= amount  # Modifying the private attribute
        else:
            print("Invalid withdrawal amount.")
    def get_balance(self):
        """Method to get the balance."""
        return self.__balance
# Creating an instance of the BankAccount class
account = BankAccount("John Doe", 1000)
# Accessing public attribute directly
print(account.account_holder) 
# Attempting to access private attribute directly (This will raise an AttributeError)
# print(account.__balance)  # Uncommenting this line will result in an error
# Using public methods to access and modify private attribute
account.deposit(500)
account.withdraw(200)
# Accessing the private attribute via a public method
print("Balance:", account.get_balance())  

Output

John Doe
Balance: 1300

Explanation:

  • The __balance attribute is private, meaning it cannot be accessed directly from outside the class.
  • The deposit() and withdraw() methods are used to modify the private balance, ensuring that changes to the balance occur only in a controlled manner.
  • To access the private balance, we use the get_balance() method, which is a controlled way to view the internal data.

In this case, private encapsulation ensures that the __balance attribute cannot be modified or accessed directly from outside the class. Instead, any changes to the balance must go through the public methods, which perform checks (like ensuring positive deposits or valid withdrawals). 

This protects the integrity of the data and prevents unwanted changes.

Encapsulation in Python Using Protected Members

In Python, protected members are attributes or methods that are intended for internal use within the class and its subclasses. These members are prefixed with a single underscore (_). 

While they can still be accessed from outside the class, it is recommended to treat them as protected and not directly modify them, as they are meant to be used within the class and its derived classes. 

Here’s an example:

class Car:
    def __init__(self, brand, model, year):
        self._brand = brand  # Protected attribute
        self._model = model  # Protected attribute
        self._year = year  # Protected attribute
    def display_info(self):
        """Method to display car information."""
        print(f"Car Brand: {self._brand}, Model: {self._model}, Year: {self._year}")
class ElectricCar(Car):
    def __init__(self, brand, model, year, battery_capacity):
        super().__init__(brand, model, year)  # Inherit protected attributes
        self._battery_capacity = battery_capacity  # Protected attribute
    def display_electric_car_info(self):
        """Method to display electric car information."""
        self.display_info()
        print(f"Battery Capacity: {self._battery_capacity} kWh")
# Creating an instance of ElectricCar class
electric_car = ElectricCar("Tesla", "Model S", 2022, 100)
# Accessing protected attributes inside the class and subclass
electric_car.display_electric_car_info()
# Accessing protected attributes directly (not recommended)
print(f"Car Brand: {electric_car._brand}")  

Output

Car Brand: Tesla, Model: Model S, Year: 2022
Battery Capacity: 100 kWh
Car Brand: Tesla

Explanation:

  • The _brand, _model, and _year attributes are protected. While these attributes can be accessed or modified directly from outside the class, this practice is discouraged.
  • The ElectricCar class inherits from the Car class, and as a subclass, it can access the protected attributes of its parent class. This is a key feature of protected members: allowing inherited classes to access internal data while still keeping it somewhat private from the outside world.
  • The method display_info() is used to display the information of the car, and it’s inherited by the subclass to be used without modification.

In this example, protected encapsulation strikes a balance between allowing access and maintaining some level of privacy. 

This is particularly useful when working with inherited classes, where the child class needs to access some data from the parent class but shouldn't expose those details to the outside world.

This approach is an excellent encapsulation in Python example where data can be shared between parent and child classes while still offering some protection against external manipulation.

FAQs

1. What is encapsulation in Python?

A. Encapsulation in Python is the concept of bundling data (attributes) and methods (functions) that manipulate the data into a single unit, i.e., a class. It restricts direct access to some of an object's components, which can prevent the accidental modification of data.

2. What are the types of encapsulation in Python?

A. The main types of encapsulation in Python are public, protected, and private members. Public members can be accessed directly, while protected and private members are intended for internal use and are typically accessed through methods.

3. Can you provide an example of encapsulation in Python?

A. Sure! In the encapsulation in Python example, attributes like _brand in the Car class are protected, meaning they can be accessed within the class or subclasses, but not from outside directly.

4. How does encapsulation improve code security?

A. Encapsulation protects data by restricting access to it and allowing controlled access via methods, ensuring the internal state remains secure and changes are tracked.

5. How do I create a private member in Python?

A. Private members in Python are created by prefixing the variable name with double underscores (__). This prevents direct access from outside the class, making the data more secure.

6. Can I access protected members outside the class in Python?

A. While you can access protected members (those prefixed with _) outside the class, it's generally discouraged as it goes against the principle of encapsulation in Python. It's meant for use within the class or subclasses.

7. How do protected members work in Python?

A. Protected members in Python are prefixed with a single underscore (_). They are accessible inside the class and its subclasses but are not intended for external access, offering a layer of protection.

8. How does encapsulation relate to inheritance in Python?

A. Encapsulation helps in inheritance by allowing child classes to inherit protected members while preventing direct access to these members from outside the class. It enables controlled data access.

9. What are the advantages of using encapsulation in Python?

A. Encapsulation improves code security, reduces complexity, increases modularity, and helps in maintaining code by providing controlled access to an object's internal state.

10. Can encapsulation prevent direct modification of data in Python?

A. Yes, encapsulation in Python example uses private or protected members to prevent unauthorized modification of an object's data, offering better data integrity.

11. What is the difference between protected and private members in Python?

A. Protected members (prefixed with _) are intended for internal use within the class and subclasses, while private members (prefixed with __) are more strictly hidden and cannot be accessed outside the class.

image

Take our Free Quiz on Python

Answer quick questions and assess your Python knowledge

right-top-arrow
image
Join 10M+ Learners & Transform Your Career
Learn on a personalised AI-powered platform that offers best-in-class content, live sessions & mentorship from leading industry experts.
advertise-arrow

Free Courses

Explore Our Free Software Tutorials

upGrad Learner Support

Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)

text

Indian Nationals

1800 210 2020

text

Foreign Nationals

+918045604032

Disclaimer

1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.

2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.