×
   ❮   
PYTHON FOR DJANGO DJANGO FOR BEGINNERS DJANGO SPECIFICS Roadmap
     ❯   

OOP IN PYTHON

Class

Understanding Classes in Python

Introduction

A class in Python is a blueprint for creating objects. Classes encapsulate data and functions that operate on that data, allowing for a structured and reusable codebase. By defining a class, you can create multiple instances (objects) that share the same attributes and behavior but have different values for their attributes.

Defining a Class

To define a class in Python, you use the class keyword followed by the class name. By convention, class names are written in CamelCase. Inside the class, you define methods (functions) that belong to the class, and you can also define attributes that will be shared by all objects of the class.

Example:

class Dog:
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed

    def bark(self):
        return f"{self.name} says woof!"

# Creating an object of the Dog class
my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.bark())

In this example, the Dog class is defined with an __init__ method, which is a special method called a constructor. The __init__ method initializes the object's attributes name and breed. The class also has a method bark, which returns a string representing the dog's bark.

Creating Objects

Objects are instances of a class. When you create an object, you are essentially creating an instance of the class, with its own unique data. Each object can have different values for its attributes, but all objects of a class share the same methods.

Example:

# Creating another object of the Dog class
another_dog = Dog("Max", "Bulldog")
print(another_dog.bark())

In this example, another_dog is another instance of the Dog class with different attribute values for name and breed. It shares the bark method with the my_dog object.

Attributes and Methods

Attributes are variables that belong to a class or an object, and methods are functions that belong to a class. You can access an object's attributes and methods using the dot notation.

Example:

# Accessing attributes and methods of an object
print(my_dog.name)       # Outputs: Buddy
print(my_dog.breed)      # Outputs: Golden Retriever
print(my_dog.bark())     # Outputs: Buddy says woof!

In this example, the object's attributes name and breed are accessed directly, and the bark method is called to make the dog bark.

Instance vs. Class Attributes

Instance attributes are unique to each object, while class attributes are shared across all instances of the class. Class attributes are defined directly within the class, outside of any methods, and are accessed using the class name or an instance.

Example:

class Circle:
    pi = 3.14159  # Class attribute

    def __init__(self, radius):
        self.radius = radius  # Instance attribute

    def area(self):
        return Circle.pi * (self.radius ** 2)

# Creating an object of the Circle class
my_circle = Circle(5)
print(my_circle.area())  # Outputs: 78.53975

In this example, pi is a class attribute, while radius is an instance attribute. The area method uses both the class attribute pi and the instance attribute radius to calculate the area of the circle.

Inheritance and Method Overriding

Classes in Python can inherit attributes and methods from other classes. This is called inheritance and allows you to create a new class based on an existing class, with the option to override or extend its behavior.

Example:

class Animal:
    def sound(self):
        return "Some sound"

class Dog(Animal):
    def sound(self):
        return "Woof!"

my_dog = Dog()
print(my_dog.sound())  # Outputs: Woof!

In this example, the Dog class inherits from the Animal class and overrides the sound method to provide a specific implementation for dogs.

Encapsulation

Encapsulation is the practice of keeping an object's data private by using private attributes and providing public methods to access and modify that data. In Python, you can make an attribute private by prefixing its name with two underscores (__).

Example:

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # Private attribute

    def deposit(self, amount):
        self.__balance += amount

    def withdraw(self, amount):
        if amount <= self.__balance:
            self.__balance -= amount
            return amount
        else:
            return "Insufficient funds"

    def get_balance(self):
        return self.__balance

account = BankAccount(1000)
account.deposit(500)
print(account.get_balance())  # Outputs: 1500

In this example, the __balance attribute is private, and it can only be accessed or modified using the public methods deposit, withdraw, and get_balance.

Conclusion

Classes are fundamental building blocks in Python's Object-Oriented Programming paradigm. They allow you to define reusable blueprints for creating objects that share the same attributes and methods. By understanding and using classes effectively, you can write more modular, maintainable, and scalable code in Python.