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

OOP IN PYTHON

Object

Understanding Objects in Python

Introduction

In Python, an object is an instance of a class. Objects are the fundamental building blocks of Object-Oriented Programming (OOP) and are used to model real-world entities by combining data (attributes) and behavior (methods) within a single structure.

Creating an Object

To create an object, you simply instantiate a class by calling it as if it were a function. The resulting object will have access to the attributes and methods defined in the class.

Example:

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

    def start_engine(self):
        return f"The {self.make} {self.model}'s engine is now running."

# Creating an object of the Car class
my_car = Car("Toyota", "Corolla", 2020)
print(my_car.start_engine())

In this example, my_car is an object created from the Car class. It represents a specific car with its own make, model, and year attributes, and it can perform actions like starting its engine through the start_engine method.

Accessing Attributes and Methods

Once an object is created, you can access its attributes and methods using dot notation. Attributes store the state of the object, while methods define its behavior.

Example:

# Accessing attributes
print(my_car.make)   # Outputs: Toyota
print(my_car.model)  # Outputs: Corolla
print(my_car.year)   # Outputs: 2020

# Calling a method
print(my_car.start_engine())  # Outputs: The Toyota Corolla's engine is now running.

In this example, the object's attributes make, model, and year are accessed directly, and the start_engine method is called to simulate starting the car's engine.

Object Identity and State

Each object in Python has a unique identity, which can be thought of as the object's memory address. You can check an object's identity using the id() function. The state of an object is determined by the values of its attributes at any given time.

Example:

# Checking object identity
print(id(my_car))  # Outputs: A unique identifier (memory address)

# Modifying the state of an object
my_car.year = 2021
print(my_car.year)  # Outputs: 2021

In this example, id(my_car) returns a unique identifier for the my_car object, and the state of the object is modified by changing the value of the year attribute.

Multiple Objects

You can create multiple objects from the same class, each with its own set of attributes and independent state. These objects can interact with each other and the outside world through their methods.

Example:

# Creating multiple objects
car1 = Car("Honda", "Civic", 2019)
car2 = Car("Ford", "Mustang", 2021)

# Accessing attributes and methods
print(car1.start_engine())  # Outputs: The Honda Civic's engine is now running.
print(car2.start_engine())  # Outputs: The Ford Mustang's engine is now running.

In this example, car1 and car2 are two distinct objects of the Car class. They have different attribute values and can independently perform actions defined by the class's methods.

Objects and Memory Management

Python uses automatic memory management and garbage collection to handle objects. When an object is no longer referenced by any variables, Python's garbage collector will automatically reclaim the memory used by the object.

Example:

# Deleting an object
del car1

# car1 is no longer accessible after deletion
# print(car1.start_engine())  # This would raise an error

In this example, the car1 object is deleted using the del statement, making it no longer accessible. Python's garbage collector will eventually free up the memory used by car1.

Object Equality

In Python, there are two ways to compare objects: using == (equality operator) and is (identity operator). Understanding the difference between these two is crucial when working with objects.

Equality Operator (==)

The == operator checks whether the values of two objects are equal. It compares the data held within the objects to determine if they are equivalent.

Example:

# Using the equality operator
car1 = Car("Toyota", "Corolla", 2020)
car2 = Car("Toyota", "Corolla", 2020)

print(car1 == car2)  # Outputs: False (unless the equality method is overridden)

In this example, even though car1 and car2 have the same attribute values, == returns False because by default, the equality operator compares the identity of objects, not their values. However, you can override the __eq__ method in the class definition to compare attribute values instead.

Identity Operator (is)

The is operator checks whether two objects are the same instance in memory. It compares the identity of the objects, which is determined by their memory address.

Example:

# Using the identity operator
car3 = car1

print(car1 is car2)  # Outputs: False
print(car1 is car3)  # Outputs: True

In this example, car1 is car2 returns False because they are two separate instances of the Car class, even though they have the same attribute values. On the other hand, car1 is car3 returns True because car3 is just another reference to the same object as car1.

Overriding Equality

To make == compare the attribute values of objects instead of their identities, you can override the __eq__ method in your class.

Example:

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

    def __eq__(self, other):
        if isinstance(other, Car):
            return (self.make == other.make and
                    self.model == other.model and
                    self.year == other.year)
        return False

# Now car1 == car2 will compare attribute values
print(car1 == car2)  # Outputs: True

In this example, the __eq__ method is overridden to compare the make, model, and year attributes of the Car objects. Now, car1 == car2 returns True because their attribute values are the same.