Python encapsulation: hiding the internal implementation of classes and managing access to attributes and methods.

онлайн тренажер по питону
Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

A self-study guide for Python 3 compiled from the materials on this site. Primarily intended for those who want to learn the Python programming language from scratch.

What is encapsulation in Python

Encapsulation is one of the basic principles of object-oriented programming (OOP), which allows you to hide the internal implementation of an object and provide controlled access to its data through special methods. In Python, encapsulation is implemented using access modifiers and accessor methods.

Basics of encapsulation in Python

Python uses a double underscore __ before the attribute name to create private attributes. This makes attributes inaccessible to direct access from outside the class, ensuring data protection.

Example 1: Car class with encapsulation

class Car:
    def __init__(self, make, model, year):
self.__make = make # Private attribute
        self.__model = model
        self.__year = year

    def get_make(self):
        return self.__make

    def get_model(self):
        return self.__model

    def get_year(self):
        return self.__year

    def set_make(self, make):
        self.__make = make

    def set_model(self, model):
        self.__model = model

    def set_year(self, year):
if year > 1900: # Add validation
            self.__year = year
        else:
print("Incorrect release year")

    def display_info(self):
print(f"Brand: {self.__make}, Model: {self.__model}, Year: {self.__year}")

# Using the class
car = Car("Toyota", "Camry", 2020)
car.display_info() # Output: Brand: Toyota, Model: Camry, Year: 2020

# Changing attributes via methods
car.set_year(2021)
car.display_info() # Output: Brand: Toyota, Model: Camry, Year: 2021

# Attempting to access attributes directly will cause an error
# print(car.__make)  # AttributeError: 'Car' object has no attribute '__make'

Data validation encapsulation

One of the main advantages of encapsulation is the ability to add checks when object data changes.

Example 2: Employee class with validation

class Employee:
    def __init__(self, name, age, salary):
        self.__name = name
        self.__age = age
        self.__salary = salary

    def get_name(self):
        return self.__name

    def get_age(self):
        return self.__age

    def get_salary(self):
        return self.__salary

    def set_name(self, name):
        if name and len(name.strip()) > 0:
self.__name = name.strip()
else:
print("Name cannot be empty")

    def set_age(self, age):
        if 18 <= age <= 65:
            self.__age = age
        else:
print("Age must be between 18 and 65 years old")

    def set_salary(self, salary):
        if salary > 0:
            self.__salary = salary
        else:
print("Salary should be positive")

    def display_info(self):
print(f"Name: {self.__name}, Age: {self.__age}, Salary: {self.__salary} rub.")

# Creating and using
the employee object = Employee("Ivan", 30, 50,000)
employee.display_info() # Output: Name: Ivan, Age: 30, Salary: 50,000 rubles.

# Change via validated methods
employee.set_salary(60000)
employee.set_age(35)
employee.display_info() # Output: Name: Ivan, Age: 35, Salary: 60,000 rub.

Practical example: Bank account

Let's consider a more complex example with a bank account, where encapsulation is critically important for the security of transactions.

Example 3: BankAccount class

class BankAccount:
    def __init__(self, account_number, initial_balance=0):
        self.__account_number = account_number
        self.__balance = initial_balance
        self.__transaction_history = []

    def get_account_number(self):
        return self.__account_number

    def get_balance(self):
        return self.__balance

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            self.__transaction_history.append(f"Replenishment: +{amount}")
print(f"Account replenished by {amount}. Current balance: {self.__balance}")
else:
print("The deposit amount must be positive")

    def withdraw(self, amount):
        if amount <= 0:
print("Withdrawal amount must be positive")
elif amount > self.__balance:
            print("Insufficient funds in the account")
else:
self.__balance -= amount
            self.__transaction_history.append(f"Withdrawal: -{amount}")
print(f"Withdrawn {amount}. Current balance: {self.__balance}")

    def get_transaction_history(self):
        return self.__transaction_history.copy()

    def display_info(self):
print(f"Account number: {self.__account_number}, Balance: {self.__balance} rub.")

# Using the class
account = BankAccount("12345678", 1000)
account.display_info() # Output: Account number: 12345678, Balance: 1000 rub.

# Operations with the account
account.deposit(500) # The account is topped up by 500. Current balance: 1,500
account.withdraw(300) # Withdrawn 300. Current balance: 1200
account.withdraw(2000) # Insufficient funds in the account

# View the history of operations
history = account.get_transaction_history()
for transaction in history:
    print(transaction)

Encapsulation in the Student class

Example 4: Student class with extended validation

class Student:
    def __init__(self, name, age, grade):
        self.__name = name
        self.__age = age
        self.__grade = grade
        self.__subjects = {}

    def get_name(self):
        return self.__name

    def get_age(self):
        return self.__age

    def get_grade(self):
        return self.__grade

    def set_name(self, name):
        if name and len(name.strip()) > 0:
self.__name = name.strip()
else:
print("Name cannot be empty")

    def set_age(self, age):
        if 16 <= age <= 25:
            self.__age = age
        else:
print ("The student's age must be between 16 and 25 years old")

    def set_grade(self, grade):
        if 0 <= grade <= 100:
            self.__grade = grade
        else:
            print("The score should be from 0 to 100")

    def add_subject(self, subject_name, score):
        if 0 <= score <= 100:
            self.__subjects[subject_name] = score
        else:
print("Subject grade should be from 0 to 100")

    def get_subjects(self):
        return self.__subjects.copy()

    def calculate_average(self):
        if self.__subjects:
            return sum(self.__subjects.values()) / len(self.__subjects)
        return 0

    def display_info(self):
        print(f"Name: {self.__name}, Age: {self.__age}, Overall grade: {self.__grade}")
if self.__subjects:
            print("Items:")
for subject, score in self.__subjects.items():
print(f"{subject}: {score}")
print(f"Average score: {self.calculate_average():.2f}")

# Creating and using
the student object = Student("Anna", 20, 90)
student.display_info()

# Adding subjects
student.add_subject("Mathematics", 95)
student.add_subject("Physics", 88)
student.add_subject("Chemistry", 92)

student.display_info()

# Changing the grade with validation
student.set_grade(95)
student.set_grade(105) # Incorrect value, will not change the grade

Advantages of encapsulation

  1. Data protection: Prevents accidental or incorrect modification of important attributes of an object
  2. Access control: Allows you to add checks and restrictions when changing data
  3. Modularity: Simplifies code maintenance and modification without affecting other parts of the program
  4. Security: Hides the internal implementation from external influences

Conclusion

Encapsulation in Python is a powerful tool for creating reliable and secure object-oriented programs. The use of private attributes and accessor methods allows you to control access to object data and ensures program integrity. Proper use of encapsulation makes the code more readable, secure, and easy to maintain.

 

categories

  • Introduction to Python
  • Python Programming Basics
  • Control Structures
  • Data Structures
  • Functions and Modules
  • Exception Handling
  • Working with Files and Streams
  • File System
  • Object-Oriented Programming (OOP)
  • Regular Expressions
  • Additional Topics
  • General Python Base