Classes

Classes are used to create objects that have properties (attributes) and behaviors (methods). Classes provide a way to define a blueprint or template for creating objects of a specific type.

Let's take an example of a `Car` class to understand how classes work:

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

    def start_engine(self):
        print("Engine started!")

    def stop_engine(self):
        print("Engine stopped!")

    def drive(self):
        print("Car is being driven!")
In this code, we define a `Car` class. The `__init__` method is a special method called a constructor, which is executed when a new object is created from the class. It initializes the attributes `make`, `model`, and `year` with the values passed as arguments.

The class also has three methods: `start_engine`, `stop_engine`, and `drive`. These methods define the behaviors of the `Car` objects. When called, they perform specific actions related to the car, such as starting the engine, stopping the engine, or driving the car.

To create an object (instance) of the `Car` class, we can do the following:

my_car = Car("Toyota", "Camry", 2022)
In this code, we create a new `Car` object called `my_car` by calling the `Car` class and passing the make, model, and year as arguments.

We can then access the attributes and call the methods of the `my_car` object:

print(my_car.make)  # Output: Toyota
print(my_car.model)  # Output: Camry
print(my_car.year)  # Output: 2022

my_car.start_engine()  # Output: Engine started!
my_car.drive()  # Output: Car is being driven!
my_car.stop_engine()  # Output: Engine stopped!
Toyota
Camry
2022
Engine started!
Car is being driven!
Engine stopped!
In this code, we access the attributes `make`, `model`, and `year` of the `my_car` object and print their values. We also call the methods `start_engine`, `drive`, and `stop_engine` to perform the corresponding actions on the `my_car` object.

Classes allow us to create objects that encapsulate data and behavior, making your code more organized and modular. They provide a way to define custom types and create multiple instances (objects) of those types.