Gyaan

Classes and Objects

beginner classes objects OOP init

A class is a blueprint for creating objects. Think of it like a cookie cutter — the class defines the shape, and each cookie we stamp out is an object (also called an instance).

Defining a Class

We use the class keyword. The __init__ method runs automatically when we create a new object — it’s where we set up the initial state.

class Dog:
    species = "Canis familiaris"  # class attribute — shared by all dogs

    def __init__(self, name, age):
        self.name = name  # instance attribute — unique to each dog
        self.age = age

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

What Is self?

Every method in a class receives self as its first argument. It’s a reference to the current instance. In simple language, self is how the object talks about itself — “my name”, “my age”.

Python passes self automatically. We never need to do it manually.

Creating Objects

We call the class like a function. Python creates the object, then calls __init__ on it.

buddy = Dog("Buddy", 3)
max = Dog("Max", 5)

print(buddy.name)    # Buddy
print(max.bark())    # Max says Woof!
print(buddy.species) # Canis familiaris — shared across all instances

Instance vs Class Attributes

  • Class attributes are defined directly in the class body (like species above). They’re shared by every instance.
  • Instance attributes are defined inside __init__ with self.something. Each object gets its own copy.
buddy.species = "Robot Dog"  # creates an instance attribute, shadows the class one
print(buddy.species)  # Robot Dog
print(max.species)    # Canis familiaris — unchanged

__str__ and __repr__

By default, printing an object gives us something ugly like <__main__.Dog object at 0x...>. We can fix that with two special methods:

  • __str__ — the “pretty” version for end users (what print() uses)
  • __repr__ — the “developer” version (what the REPL shows, should ideally be unambiguous)
class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"{self.name}, {self.age} years old"

    def __repr__(self):
        return f"Dog(name='{self.name}', age={self.age})"

buddy = Dog("Buddy", 3)
print(buddy)       # Buddy, 3 years old  (__str__)
print(repr(buddy)) # Dog(name='Buddy', age=3)  (__repr__)

In simple language, a class is just a way to bundle data and behavior together. We define the template once, then stamp out as many objects as we need — each with their own state but sharing the same methods.