What is Encapsulation and access specifiers in Python OOPs?
In simple words, when we bindup multiple methods and attributes in a single class, that is called encapsulation.
The word encapsulation comes from Capsule where we bind up the ingredients in a single wrap.
Encapsulation is the practice of hiding the internal state of an object and requiring all interaction to occur through an object's methods. This helps to maintain the integrity of the data and control how it is accessed or modified.
What are Access modifiers:
Access modifiers in Python are used to control the visibility and accessibility of class members (attributes and methods). Python has three types of access modifiers:
- Public
- Protected
- Private
1) Public:
Members (attributes or methods) declared public can be accessed from anywhere, both inside and outside the class.
2) Protected:
Members declared protected are intended to be accessible only within the class and its subclasses. In Python, this is indicated by a single underscore (_) before the member name.
Modifier | Description | Syntax Example |
---|---|---|
Public | Accessible from anywhere | self.attribute |
Protected | Accessible within the class and subclasses | self._attribute |
Private | Accessible only within the class | self.__attribute |
3) Private:
Members declared private can only be accessed within the class itself. In Python, this is indicated by a double underscore (__) before the member name.
Example:
class Example:
def __init__(self):
self.public_attribute = "I am public" # Public attribute
self._protected_attribute = "I am protected" # Protected attribute
self.__private_attribute = "I am private" # Private attribute
def show_attributes(self):
print(self.public_attribute) # Accessible
print(self._protected_attribute) # Accessible
print(self.__private_attribute) # Accessible within the class
# Create an instance of Example
obj = Example()
# Accessing public attribute
print(obj.public_attribute) # Output: I am public
# Accessing protected attribute
print(obj._protected_attribute) # Output: I am protected
# Trying to access private attribute directly (will raise an error)
# print(obj.__private_attribute) # This will raise an AttributeError
# Accessing private attribute using name mangling
print(obj._Example__private_attribute) # Output: I am private
# Call the method to show attributes
obj.show_attributes()
Output:
I am public
I am protected
I am private
I am public
I am protected
I am private
20+ interview questions focused on encapsulation and access modifiers in Python, complete with answers and examples
Question 1. What is encapsulation in Python?
Answer: Encapsulation is the bundling of data (attributes) and methods that operate on the data into a single unit, typically a class. It restricts direct access to some of the object's components to prevent unintended interference and misuse.
Example:
class Employee:
def __init__(self, name):
self.__name = name # private attribute
def get_name(self):
return self.__name # public method to access the private attribute
emp = Employee("Alice")
print(emp.get_name())
Output:
Alice
Question 2. How does encapsulation help in data hiding?
Answer: Encapsulation allows restricting access to certain attributes and methods, protecting the integrity of the data. By using private and protected members, you can prevent unauthorized access or modifications.
Example:
class BankAccount:
def __init__(self):
self.__balance = 0 # private attribute
def deposit(self, amount):
if amount > 0:
self.__balance += amount
def get_balance(self):
return self.__balance
account = BankAccount()
account.deposit(100)
print(account.get_balance())
Output:
100
Question 3. Can you provide an example of encapsulation with validation?
Answer: Yes, encapsulation can enforce validation rules within methods before modifying attributes.
Example:
class Age:
def __init__(self):
self.__age = 0 # private attribute
def set_age(self, age):
if 0 <= age <= 120:
self.__age = age
else:
raise ValueError("Invalid age")
def get_age(self):
return self.__age
person = Age()
person.set_age(25)
print(person.get_age())
Output:
25
Question 4. What is the purpose of getter and setter methods?
Answer: Getter methods allow access to private attributes, while setter methods enable controlled modification of those attributes, often with validation.
Example:
class Product:
def __init__(self, price):
self.__price = price # private attribute
def get_price(self):
return self.__price
def set_price(self, price):
if price >= 0:
self.__price = price
else:
raise ValueError("Price cannot be negative")
item = Product(100)
item.set_price(150)
print(item.get_price())
Output:
150
Question 5. How does encapsulation promote code maintainability?
Answer: Encapsulation allows for changes in the internal implementation without affecting external code that relies on the class. It makes the codebase more modular and easier to maintain.
Example:
class Circle:
def __init__(self, radius):
self.__radius = radius
def area(self):
return 3.14 * self.__radius ** 2
circle = Circle(5)
print(circle.area())
Output:
78.5
Question 6. What is name mangling in Python?
Answer: Name mangling is a technique used in Python to make private variables in a class harder to access from outside the class by prefixing the variable name with an underscore and the class name.
Example:
class Example:
def __init__(self):
self.__value = 10 # private attribute
obj = Example()
print(obj._Example__value)
Output:
10
Question 7. What are the three types of access modifiers in Python?
Answer: The three types of access modifiers are:
- Public: Accessible from anywhere.
- Protected: Accessible within the class and its subclasses.
- Private: Accessible only within the class itself.
Question 8. How do you declare a public attribute in a Python class?
Answer: Public attributes can be declared without any special prefix.
Example:
class Student:
def __init__(self, name):
self.name = name # public attribute
s = Student("John")
print(s.name)
Output:
John
Question 9. What is a protected attribute, and how is it defined in Python?
Answer: A protected attribute is defined with a single underscore prefix. It suggests that the attribute should not be accessed directly outside the class or its subclasses.
Example:
class Parent:
def __init__(self):
self._protected_var = "I am protected" # protected attribute
class Child(Parent):
def show_var(self):
print(self._protected_var) # Accessing protected attribute
c = Child()
c.show_var()
Output:
I am protected
Question 10. Can protected attributes be accessed outside the class?
Answer: Yes, protected attributes can be accessed outside the class but are discouraged to be accessed directly. They are meant for internal use and inheritance.
Example:
class Base:
def __init__(self):
self._protected_var = "Accessible but discouraged" # protected attribute
b = Base()
print(b._protected_var)
Output:
Accessible but discouraged
Question 11. How do you declare a private attribute in a Python class?
Answer: A private attribute is declared by prefixing its name with double underscores.
Example:
class Example:
def __init__(self):
self.__private_var = "I am private" # private attribute
obj = Example()
print(obj.__private_var)
Output:
AttributeError: 'Example' object has no attribute '__private_var'
Question 12. What happens if you try to access a private attribute directly?
Answer: If you try to access a private attribute directly from outside the class, it raises an AttributeError.
Example:
class Secret:
def __init__(self):
self.__hidden = "Can't see me!"
sec = Secret()
print(sec.__hidden)
Output:
AttributeError: 'Secret' object has no attribute '__hidden'
Question 13. What is the significance of using access modifiers?
Answer: Access modifiers help control the visibility of class members, enhancing data security, maintaining data integrity, and promoting proper encapsulation practices.
Question 14. How would you access a private variable using name mangling?
Answer: You can access a private variable using name mangling by prefixing the variable name with an underscore followed by the class name.
Example:
class Sample:
def __init__(self):
self.__secret = "This is a secret!"
obj = Sample()
print(obj._Sample__secret)
Output:
This is a secret!
Question 15. What is the difference between public and protected members?
Answer: Public members can be accessed from anywhere, while protected members are intended to be accessed only within the class and its subclasses. Protected members discourage direct access from outside the class.
Question 16. Can subclasses access private members of a superclass?
Answer: No, subclasses cannot access private members of a superclass directly. Private members are only accessible within the class that defines them.
Example:
class Base:
def __init__(self):
self.__private_var = "I'm private"
class Derived(Base):
def access_private(self):
# print(self.__private_var) # Raises AttributeError
d = Derived()
d.access_private()
Output:
d = Derived()
IndentationError: expected an indented block after function definition on line 6
Question 17. How would you implement a simple class with all three types of attributes?
Answer: Here’s a simple implementation demonstrating all three types of access modifiers.
Example:
class AccessModifiers:
def __init__(self):
self.public_var = "Public" # Public
self._protected_var = "Protected" # Protected
self.__private_var = "Private" # Private
def show_vars(self):
print(self.public_var)
print(self._protected_var)
print(self.__private_var)
obj = AccessModifiers()
obj.show_vars()
Output:
Public
Protected
Private
Question 18. Why might you want to use a protected attribute instead of a private attribute?
Answer: You might want to use a protected attribute when you expect the attribute to be accessed or modified by subclasses while still discouraging direct access from outside the class. It allows for flexibility in inheritance.
Question 19. What are some best practices for using access modifiers in Python?
Answer: Best practices include:
- Use public attributes for data that should be accessible to everyone.
- Use protected attributes for data that is meant for internal use and can be inherited.
- Use private attributes for data that should not be exposed outside the class.
- Always provide public methods (getters and setters) to interact with private attributes.
Question 20. Can access modifiers be overridden in subclasses?
Answer: Public and protected members can be overridden in subclasses, but private members cannot be accessed directly. However, they can be redefined in the subclass with a different name due to name mangling.
Example:
class Base:
def __init__(self):
self._protected_var = "Protected in Base"
self.__private_var = "Private in Base"
class Derived(Base):
def __init__(self):
super().__init__()
self._protected_var = "Protected in Derived"
self.__private_var = "Private in Derived"
obj = Derived()
print(obj._protected_var) # Output: Protected in Derived
print(obj.__private_var)
Output:
Protected in Derived
ERROR!
Traceback (most recent call last):
File "<main.py>", line 14, in <module>
AttributeError: 'Derived' object has no attribute '__private_var'
Tags:
Leave a comment
You must be logged in to post a comment.