Public vs. Private Attributes and Getter/Setter Methods
Lesson Overview
This lesson covers how to control access to object data using getter and setter methods. It also introduces Public Attributes (accessible from anywhere) and Private Attributes (hidden inside the class). Getters and setters allow you to safely retrieve or modify these private attributes, often adding checks to ensure data is valid before changing it
Lesson Content
The Need for Security: Protecting the Bank Vault
You already know how to update data directly (like car.speed = 100). While this is fine for simple things like a car's color, imagine if we were dealing with a Bank Account.
If we used the "Open Hood" approach here, anyone could accidentally set a negative balance or—even worse—a random person could directly change an account holder's name or PIN without any verification. That is not okay. We need "Security Guards" to control who sees the data and how it gets changed.
The Solution: Private Variables
To solve this, Python allows us to make variables Private. This effectively locks the data inside a safe. You can't just reach in and grab it anymore; the direct access is blocked.
In Python, we distinguish between public and private data using underscores.
- Public:
self.attribute(Accessible anywhere) - Private:
self.__attribute(Hidden, typically only accessible inside the class)
class BankAccount:
def __init__(self, name, balance):
self.name = name # Public: Anyone can see the name
self.__balance = balance # Private: Hidden inside the vault!
account = BankAccount("Ajay", 1000)
# We can access the public variable easily
print(account.name) # Output: Ajay
# But trying to access the private variable directly causes an error!
# print(account.__balance)
# AttributeError: 'BankAccount' object has no attribute '__balance'Now the data is safe, but we have a new problem: How do we use the money if it's locked away? We need a controlled way to interact with private variable
Controlled Access: Getter and Setter Methods
Since we can't touch the private variable directly, we create public methods that act as intermediaries (like bank representative). These are called Getters and Setters.
- Getter Method: Allows you to read the data (read-only access).
- Setter Method: Allows you to change the data, but only after passing specific security or quality checks.
This ensures that the data is never corrupted or misused.
class BankAccount:
def __init__(self, name, balance):
self.name = name # Public variable: Anyone can see the name
self.__balance = balance # Private variable: Hidden inside the vault!
# --- GETTER METHOD (The "Read-Only" Window) ---
def get_balance(self):
# We can add logic here: e.g., Log that someone checked the balance
return self.__balance #self.__balance can only be accessed inside class defination
# --- SETTER METHOD (The "Security Guard") ---
def set_balance(self, new_amount):
# We add a QUALITY CHECK (Validation)
if new_amount < 0:
print("Error: Balance cannot be negative!")
else:
self.__balance = new_amount
print(f"Success: Balance updated to {self.__balance}")
#Deposit
def deposit(self, deposit_amount):
if deposit_amount <= 0: # Data Quality Check
print("Error: Negative ammount cannot be deposited !")
else:
balance = self.get_balance() # use getter method to retrive current balance
new_balance = balance + deposit_amount # calculate the new balance by adding deposite amount
self.set_balance(new_balance) # Update the balance by using the setter method.
# Creating the account
my_account = BankAccount("Ajay", 1000)
# 1. RETRIEVING DATA (Using the Getter)
# print(my_account.__balance) # This would fail
print(my_account.get_balance()) # Success: Log: Balance checked... 1000
my_account.set_balance(-200) # The Security check stops us!
# Output: Error: Balance cannot be negative!
my_account.set_balance(5000) # Valid data passes through.
# Output: Success: Balance updated to 5000Getter and Setter methods are essentially standard instance methods; there is no special syntax difference in how they are defined. We simply label them "Getters" and "Setters" based on their purpose: a Getter is designed specifically to retrieve (get) a private attribute's value, and a Setter is designed specifically to update (set) that value with validation. While technically just functions that use self, this naming convention helps programmers instantly understand that these methods are the designated "gatekeepers" for accessing protected data.
Summary
Getters and setters provide a layer of security and control. They separate the internal data (private attributes) from the external use (public methods), ensuring your objects always stay in a valid and safe state.By using this pattern, we stop people from bypassing the rules via dot notation (account.balance = -100) and force them to go through our logic (account.set_balance(-100)), keeping the system secure.