Encapsulation in Python
Encapsulation is one of the core principles of Object-Oriented Programming (OOP). It is the concept of restricting access to certain details of an object's data and only exposing specific parts of the object to the outside world. In Python, encapsulation is achieved by using private and public attributes, methods, and by providing controlled access to an object's data through getter and setter methods.
Understanding Encapsulation
In Python, encapsulation is typically achieved by using the following:
- Public Attributes: These are accessible from outside the class and can be modified directly.
- Private Attributes: These are not accessible directly from outside the class, and their access is controlled through getter and setter methods.
- Getters and Setters: These methods are used to retrieve (get) or modify (set) the values of private attributes, ensuring that the data is validated before use.
Encapsulation helps in protecting an object’s internal state and ensures that the data is used in a controlled manner, preventing unintended interference.
Encapsulation Example
Let’s look at an example of how encapsulation works in Python by creating a Person class, where we encapsulate the age attribute to make sure it is set correctly.
1. Define the Class with Encapsulation
In this example, the Person class will have a private attribute _age
, and we will use getter and setter methods to control how the age is accessed and modified.
class Person:
def __init__(self, name, age):
self.name = name
self._age = age # Private attribute
def get_age(self):
return self._age
def set_age(self, age):
if age > 0:
self._age = age
else:
print("Age must be a positive number.")
class Person:
def __init__(self, name, age):
self.name = name
self._age = age # Private attribute
def get_age(self):
return self._age
def set_age(self, age):
if age > 0:
self._age = age
else:
print("Age must be a positive number.")
2. Create an Object and Access Private Attributes
Now, let's create a Person object and see how we can use the getter and setter methods to access and modify the age attribute.
# Create an instance of the Person class
person = Person("Alice", 30)
# Access the age using the getter method
print(person.get_age()) # Output: 30
# Change the age using the setter method
person.set_age(35)
print(person.get_age()) # Output: 35
# Attempt to set an invalid age
person.set_age(-5) # Output: Age must be a positive number.
# Create an instance of the Person class
person = Person("Alice", 30)
# Access the age using the getter method
print(person.get_age()) # Output: 30
# Change the age using the setter method
person.set_age(35)
print(person.get_age()) # Output: 35
# Attempt to set an invalid age
person.set_age(-5) # Output: Age must be a positive number.
As you can see, the private attribute _age
is accessed through the get_age()
method, and it is modified using the set_age()
method. The setter method also validates the age before updating it, ensuring the integrity of the data.
Private and Public Attributes
In Python, if an attribute starts with one underscore (like _age), it means we shouldn’t use it directly from outside the class—but Python still allows it. If it starts with two underscores (like __age), Python changes its name behind the scenes to make it harder to access. This is called name mangling, and it helps protect the data inside the class from being changed by mistake.
Public Attribute Example
class Person:
def __init__(self, name, age):
self.name = name # Public attribute
self.age = age # Public attribute
person = Person("Bob", 25)
print(person.name) # Output: Bob
print(person.age) # Output: 25
class Person:
def __init__(self, name, age):
self.name = name # Public attribute
self.age = age # Public attribute
person = Person("Bob", 25)
print(person.name) # Output: Bob
print(person.age) # Output: 25
Private Attribute Example
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age # Private attribute
person = Person("Charlie", 28)
print(person.name) # Output: Charlie
# print(person.__age) # Error: 'Person' object has no attribute '__age'
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age # Private attribute
person = Person("Charlie", 28)
print(person.name) # Output: Charlie
# print(person.__age) # Error: 'Person' object has no attribute '__age'
In the second example, __age
is considered private, and directly accessing it outside the class will result in an error.
Using Getters and Setters
Getters and setters provide controlled access to private attributes. Instead of directly accessing or modifying an attribute, you use the getter and setter methods to interact with the data, ensuring data validation and encapsulation.
Getter and Setter Example
class Employee:
def __init__(self, name, salary):
self.name = name
self.__salary = salary # Private attribute
def get_salary(self):
return self.__salary
def set_salary(self, salary):
if salary >= 0:
self.__salary = salary
else:
print("Salary must be non-negative.")
class Employee:
def __init__(self, name, salary):
self.name = name
self.__salary = salary # Private attribute
def get_salary(self):
return self.__salary
def set_salary(self, salary):
if salary >= 0:
self.__salary = salary
else:
print("Salary must be non-negative.")
This example shows how the Employee
class encapsulates the __salary
attribute. We provide a getter method get_salary()
to access the salary and a setter method set_salary()
to modify it, with validation to ensure that the salary is non-negative.
Frequently Asked Questions
What is encapsulation in Python?
What is encapsulation in Python?
Encapsulation is the concept of hiding an object's internal state and only allowing access through well-defined methods. In Python, it is achieved using private attributes and getter/setter methods.
How do you create private attributes in Python?
How do you create private attributes in Python?
You can make an attribute private in Python by prefixing it with a double underscore (e.g., __age
). This triggers name mangling and restricts direct access from outside the class.
What are getters and setters in Python?
What are getters and setters in Python?
Getters and setters are methods that allow you to safely access and update private attributes. They help in data validation and control how attributes are read or modified.
Is encapsulation mandatory in Python?
Is encapsulation mandatory in Python?
Encapsulation is not mandatory in Python, but it is a best practice in object-oriented programming. It helps organize code, protects data, and improves maintainability.
What is name mangling in Python?
What is name mangling in Python?
Name mangling is a mechanism Python uses for attributes with double underscores. It changes the attribute name internally to avoid accidental access, making it harder to access from outside the class.
What's Next?
Up next, we'll dive into the concept of Polymorphism, another key principle of Object-Oriented Programming. You'll learn how different classes can share the same method names but behave differently, allowing for more flexible and reusable code.