Python Encapsulation Tutorial

In Python, encapsulation represents a core principle of object-oriented programming (OOP). This concept pertains to a class as a grouping of data (variables) and the associated methods that manipulate that data.

Encapsulation limits direct access to certain elements of an object, thereby helping to prevent unintended interference and potential data corruption.

How does Encapsulation Work in Python?

In Python, encapsulation is achieved by preventing users from directly interacting with specific components of an object, while still providing access to those components through alternative methods.

Access can be controlled using different access modifiers :

  • Public Attribute: Accessible from anywhere.
  • Protected Attributes (_singleUnderscore ) : Not intended for public use, but still accessible.
  • Private Attributes (__doubleUnderscore): Not directly accessible from outside the class.
Member Type Syntax Accessible Inside Class Accessible in Subclasses Accessible Outside Class
Public self.var Yes Yes Yes
Protected self._var Yes Yes (Recommended inside subclasses only) Yes (Not recommended)
Private self.__var Yes No (Unless using name mangling) No (Direct access restricted)

Implementation of Encapsulation in Python

Python uses three levels of access control for class members:

  • public,
  • protected, and
  • private.

Let's explore each with examples.

Public Members

Public members are accessible from any location, including within the class itself, from outside the class, and within any derived (child) classes.

  • Usage: There should be no underscore preceding the variable name.
  • Python Public Members Example

Let us consider an example to illustrate the concept of public members in Python.

Example

Example

class Car:

    def __init__(self, brand, model):

        self.brand = brand  # Public attribute

        self.model = model  # Public attribute

    def display(self):

        print(f"Car: {self.brand} {self.model}")

# Creating an object

car = Car("Toyota", "Corolla")

# Accessing public members

print(car.brand)

print(car.model)

# Calling public method

car.display()

Output:

Output

Toyota

Corolla

Car: Toyota Corolla

Explanation:

The public attributes (brand, model) will be available for access from outside the class. Additionally, the display method, which is also designated as public, can be invoked from other classes.

Protected Members

Protected attributes are denoted by a single underscore (_variable).

  • Usage: These can be accessed from outside the class, yet they are intended to be used only within the class itself and its subclasses (this is a convention rather than a strict rule).
  • Python Protected Members Example

Let us consider an example to illustrate the concept of protected members in Python.

Example

Example

class Car:

    def __init__(self, brand, model, engine):

        self.brand = brand  # Public attribute

        self._model = model  # Protected attribute

        self._engine = engine  # Protected attribute

    def _show_details(self):  # Protected method

        print(f"Brand: {self.brand}, Model: {self._model}, Engine: {self._engine}")

class ElectricCar(Car):

    def __init__(self, brand, model, battery_capacity):

        super().__init__(brand, model, "Electric")

        self.battery_capacity = battery_capacity

    def show_info(self):

        self._show_details()  # Accessing protected method from subclass

        print(f"Battery: {self.battery_capacity} kWh")

# Creating an object of ElectricCar

tesla = ElectricCar("Tesla", "Model S", 100)

# Accessing protected members from subclass

tesla.show_info()

# Accessing protected members outside the class (not recommended)

print(tesla._model)  # Works, but not recommended

Output:

Output

Brand: Tesla, Model: Model S, Engine: Electric

Battery: 100 kWh

Model S

Explanation:

The attributes model and engine are designated as protected, while the method showdetails is also classified as protected. These elements can be accessed within subclasses; however, it is generally advised against directly utilizing them outside of their defining class.

Private Members

Private attributes are denoted by double underscores (__variable).

  • Usage: Such members cannot be accessed directly from outside the class.
  • Python Private Members Example

Let's consider an illustration to showcase the concept of private members in Python.

Example

Example

class BankAccount:

    def __init__(self, account_number, balance):

        self.account_number = account_number  # Public attribute

        self.__balance = balance  # Private attribute

    def get_balance(self):  # Getter method

        return self.__balance

    def set_balance(self, amount):  # Setter method

        if amount >= 0:

            self.__balance = amount

        else:

            print("Invalid amount! Balance cannot be negative.")

# Creating an account object

account = BankAccount("123456789", 1000)

# Accessing public member

print(account.account_number)  # Works fine

# Trying to access private member directly (will raise AttributeError)

# print(account.__balance)  # Uncommenting this will cause an error

# Using getter method to access private attribute

print(account.get_balance())  # Works fine

# Using setter method to update private attribute

account.set_balance(2000)

print(account.get_balance())  # Updated balance

# Accessing private attribute using name mangling (Not recommended)

print(account._BankAccount__balance)  # Works, but should be avoided

Output:

Output

123456789

1000

2000

2000

Explanation:

The attribute _balance is designated as private, which means it cannot be accessed directly. To manage access to this attribute, we employ getter (getbalance) and setter (setbalance) methods. Internally, Python alters the name of balance to BankAccount__balance, enabling access through name mangling. However, this practice is generally discouraged.

Conclusion

Encapsulation conceals the internal workings and the implementation specifics of an object's properties by restricting direct access. In Python, encapsulation is achieved using public, protected, and private members for class attributes, along with managing access through getters and setters. This practice enhances the security, maintainability, and organization of the code due to the convention-driven methodology utilized in Python.

Encapsulation in Python FAQs

1. What is Encapsulation in Python?

Encapsulation is a fundamental concept in object-oriented programming that restricts direct access to an object's data and its associated methods. Instead, access is facilitated through regulated interfaces known as public methods, which guarantees that the data remains secure and safeguarded.

2. How is Encapsulation Implemented in Python?

Encapsulation is achieved through the use of access specifiers:

  • Self Variable (self.var): Public Members are accessible from any location. Protected Members, indicated by a single underscore (_var), signify that they are intended for internal use only.
  • Double underscore(__var): This refers to Private Members, which implies that direct access to them is restricted.
  • 3. Why is Encapsulation Important?

Encapsulation Provides:

  • Intended modification is prevented so data is secured.
  • Defined methods are the only way data can be accessed meaning method controlled access is provided.
  • Structure and Modularity improves so the code becomes maintainable.
  • 4. How Do Getters and Setters Work in Encapsulation?

Private variables can be accessed through the use of getter and setter methods, which serve distinct purposes.

Example

Example

class BankAccount:

    def __init__(self, balance):

        self.__balance = balance

    def get_balance(self):  # Getter

        return self.__balance

    def set_balance(self, amount):  # Setter

        if amount >= 0:

            self.__balance = amount

        else:

            print("Invalid amount!")

account = BankAccount(1000)

print(account.get_balance())

account.set_balance(2000)

print(account.get_balance())

Output:

Output

1000

2000

5. Can Private Members Be Accessed Outside the Class in Python?

Direct access to the class attribute is prohibited, which prevents us from accessing it directly. Nevertheless, we can retrieve the private variable by utilizing name mangling. This is done by using the syntax (ClassName_privateVar).

Input Required

This code uses input(). Please provide values below: