Tech With Galvan
Courses/Python Mastery/Object-Oriented Python

__init__, self, and Methods

25 min • Beginner • Module 9

Construct objects properly and demystify self forever.

init, self, and Methods

Last lesson, you attached data to objects by hand — s1.name = "Aarav" — with nothing forcing consistency. Today, the __init__ constructor makes every object born complete, and self finally gets explained.

init — the birth function

__init__ (double underscore each side — “dunder init”) runs automatically when an object is created. It’s the setup crew:

class Student:
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks

# creating objects — arguments flow into __init__
s1 = Student("Aarav", 92)
s2 = Student("Diya", 95)

print(s1.name)     # Aarav
print(s2.name)     # Diya — each object has its OWN data

Trace the flow of Student("Aarav", 92):

  1. Python creates a fresh, empty Student object
  2. It calls __init__(self, "Aarav", 92) — self is the new object, “Aarav” and 92 are your arguments
  3. Inside, self.name = name attaches “Aarav” to that specific object
  4. The finished object is returned to s1

Now every Student is born with name and marks. No object can exist half-formed — the constructor enforces the shape.

self — the object itself

self is the most confusing word for beginners and the simplest idea once it lands: self is the object the method was called on.

class Student:
    def __init__(self, name, marks):
        self.name = name        # "attach name to THIS object"

    def introduce(self):
        print(f"I'm {self.name}, scored {self.marks}")

s1 = Student("Aarav", 92)
s2 = Student("Diya", 95)

s1.introduce()     # I'm Aarav, scored 92
s2.introduce()     # I'm Diya, scored 95

The trick: s1.introduce() secretly means introduce(s1) — Python passes the object as self automatically. Inside the method, self.name means “the name of whichever object I was called on.” That’s why s1 prints Aarav and s2 prints Diya with the same method.

The two self-rules:

  1. self is always the first parameter of every method
  2. You never pass it yourself — Python does, via the dot

Methods using their own data

Methods become powerful when they compute from the object’s attributes:

class Student:
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks

    def average(self):
        return sum(self.marks) / len(self.marks)

    def has_passed(self):
        return self.average() >= 40      # methods calling methods!

s1 = Student("Aarav", [85, 90, 78])
print(s1.average())        # 84.33...
print(s1.has_passed())     # True

self.marks inside average() refers to the calling object’s list. And has_passed calls self.average() — objects’ methods work together through self.

The full anatomy, one screen

class Student:
    def __init__(self, name, marks):     # constructor: birth setup
        self.name = name                 # attributes: the data
        self.marks = marks

    def introduce(self):                 # method: behavior
        print(f"I'm {self.name}")

    def average(self):                   # method computing from data
        return sum(self.marks) / len(self.marks)


s1 = Student("Aarav", [85, 90, 78])      # instantiation
s1.introduce()                           # method call

Read it as a sentence: “A Student is born with a name and marks; it can introduce itself and compute its average.”

Common Errors & Fixes

  • TypeError: Student() takes no arguments — you defined __init__ with a typo (_init_, __init_). Dunders need double underscores on both sides.
  • NameError: name 'self' is not defined — you forgot self as the method’s first parameter.
  • TypeError: introduce() takes 0 positional arguments but 1 was given — defined without self but called via the dot (which passes the object). Add self.
  • Attribute “disappears” — you set it on one object, read it from another. Each object’s attributes are its own.

✅ Checkpoint

  1. When does __init__ run? (Automatically, at object creation)
  2. What is self? (The object the method was called on — passed automatically)
  3. Why does s1.introduce() print Aarav and s2.introduce() print Diya? (self refers to the calling object each time)
  4. Can a method call another method? (Yes — through self)

Next: inheritance — building new classes on top of existing ones.