Data hiding

#Public
class pdata:
    def __init__(self, d):
        self.data = d

    def show(self):
        print(self.data)

p = pdata(10)
p.show()
p.data = 20
p.show()
-----------------------------------
#PPrivate
class pdata:
    def __init__(self, d):
        self.__data = d

    def show(self):
        print(self.__data)

p = pdata(10)
p.show()
p.__data = 20
p.show()
-----------------------------------------
#Private
class pdata:
    def __init__(self, d):
        self.__data = d

    def show(self):
        print(self.__data)

p = pdata(10)
p.show()
p._pdata__data = 20 #name Managing
p.show()
------------------------------
Protected
class pdata:
    def __init__(self, d):
        self._data = d

    def show(self):
        print(self._data)

p = pdata(10)
p.show()
p.pdata_data = 20
p.show()

Data hiding in Python OOP is the concept of restricting access to the internal data of an object from outside the class. 🔐 It’s a way to prevent direct modification of data and protect the object’s integrity. This is typically achieved by using a naming convention that makes attributes “private” or “protected.”


🔒 How Data Hiding Works

Python doesn’t have true private keywords like some other languages (e.g., private in Java or C++). Instead, it relies on a convention and a mechanism called name mangling to achieve a similar effect.

  • Protected Members: By convention, a single leading underscore (_) is used for attributes that are “protected.” This signals to other developers that the attribute is intended for internal use and should not be accessed directly. For example: _protected_variable. While it can still be accessed and modified, it’s a strong hint to not do so.
  • Private Members: To make an attribute “private,” you use two leading underscores (__). This triggers name mangling, a process where Python automatically renames the attribute internally to prevent accidental access. For a class named MyClass and an attribute __private_variable, Python internally renames it to _MyClass__private_variable. This makes it difficult to access from outside the class, enforcing a form of data hiding.

📜 Example with Name Mangling

Here’s a simple program to illustrate the concept.

Python

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # This is a private attribute

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            print(f"Deposited {amount}. New balance is {self.__balance}")
        else:
            print("Invalid deposit amount.")

    def get_balance(self):
        return self.__balance

# Create an instance of BankAccount
my_account = BankAccount(100)

# This works because deposit is a public method
my_account.deposit(50)

# Trying to access the private attribute directly will result in an AttributeError
try:
    print(my_account.__balance)
except AttributeError as e:
    print(f"Error: {e}")

# This is how you can technically access it (but you shouldn't!)
print(my_account._BankAccount__balance)

In this example, the __balance attribute is hidden from direct external access. You must use the public deposit() or get_balance() methods to interact with it. This ensures that the balance is only modified through controlled logic, preventing invalid negative amounts from being set directly.

The try...except block demonstrates that trying to access __balance directly results in an AttributeError. The last print statement shows how name mangling works, but it’s a workaround that goes against the principle of data hiding and should be avoided in practice.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *