Get AI summaries of any video or article — Sign up free
Python OOP Tutorial 1: Classes and Instances thumbnail

Python OOP Tutorial 1: Classes and Instances

Corey Schafer·
5 min read

Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Classes act as blueprints, while instances are the individual objects created from those blueprints.

Briefing

Python’s class system is presented as a practical way to bundle related data and behavior into reusable blueprints—especially when you need many similar objects with their own unique values. The tutorial’s core message is that classes let developers avoid repetitive, error-prone setup code by defining a single structure (a class) and then creating multiple independent objects (instances) from it.

A simple Employee class is introduced to model real-world entities. The distinction between a class and an instance is made early: the class acts as a blueprint, while each Employee created from it becomes a separate instance with its own identity in memory. Two employees created from the same Employee class are shown as distinct objects, even though they share the same underlying structure.

The tutorial then focuses on instance variables—data unique to each object. It demonstrates the manual approach first: assigning attributes like first name, last name, email, and pay directly to each employee instance. That method works, but it quickly becomes verbose and easy to get wrong (the example shows a mistake where one employee’s email assignment isn’t updated correctly). The takeaway is that manually setting attributes defeats much of the benefit of using classes.

To automate initialization, the tutorial introduces Python’s special __init__ method. This method runs automatically whenever a new instance is created. Inside __init__, the instance is received as the first argument (by convention named self), followed by the values needed to set up the object. The tutorial builds the email from first and last names and assigns pay, first, and last to instance variables like self.first, self.last, self.pay, and self.email. With __init__ in place, creating new employees becomes as simple as passing first name, last name, and pay—Python handles the rest.

Next comes behavior: methods. The tutorial shows how printing an employee’s full name can be done repeatedly with string formatting outside the class, but that repetition is exactly what methods are meant to eliminate. A full_name method is added to the Employee class, returning a combined string using self.first and self.last. Calling employee1.full_name() and employee2.full_name() produces the correct result for each instance.

A common pitfall is highlighted: forgetting the self parameter in a method definition. Without self, calling the method triggers a TypeError because Python still passes the instance automatically, meaning the method signature no longer matches what Python provides. The tutorial also compares calling the method on an instance (employee1.full_name()) versus calling it on the class (Employee.full_name(employee1)), clarifying how self gets supplied behind the scenes.

By the end, the foundational pieces are in place: creating classes, understanding class vs instance, initializing instance variables with __init__, and defining instance methods that operate correctly across all objects created from the same class. The next step previewed is class variables and how they differ from instance variables.

Cornell Notes

The tutorial builds an Employee class to show how Python OOP reduces repetition and mistakes. It distinguishes a class (blueprint) from instances (individual objects with separate memory identities). Instance variables store data unique to each instance, and the __init__ method automates setting them when new objects are created. Methods like full_name encapsulate behavior so code doesn’t need to be rewritten for every employee. The self parameter is essential because Python passes the instance automatically; omitting it causes a TypeError. Calling methods on an instance vs on the class changes whether self is supplied automatically or must be passed explicitly.

What’s the practical difference between a class and an instance in Python?

A class is the blueprint (e.g., Employee). Each time the class is called to create an object (e.g., employee1 = Employee(...)), Python produces an instance. Even if two instances come from the same class, they’re distinct objects with different identities in memory, which is why each can hold different instance-specific data.

Why are instance variables better than manually assigning attributes to each object?

Instance variables hold data unique to each instance, such as first name, last name, email, and pay. Manually assigning these for every employee is verbose and error-prone—an example shows how easy it is to forget to update an assignment for the second employee. Using __init__ centralizes that setup so every new instance gets correct values automatically.

How does __init__ change object creation?

__init__ is a special method that runs automatically when a new instance is created. It receives the instance as the first argument (self) and then the values passed during construction (first, last, pay). Inside __init__, the tutorial assigns self.first, self.last, self.pay, and builds self.email from first and last, so the caller doesn’t need to set attributes afterward.

What role does self play in class methods, and what happens if it’s omitted?

self represents the instance on which the method operates. Python automatically passes the instance as the first argument when calling an instance method like employee2.full_name(). If self is omitted from the method definition, Python still passes the instance anyway, leading to a TypeError such as “full-name takes zero positional arguments but one was given.”

How do method calls differ when invoked on an instance vs on the class?

When called on an instance (employee1.full_name()), Python automatically supplies self. When called on the class (Employee.full_name(employee1)), Python does not know which instance to use, so the instance must be passed explicitly as the argument that becomes self.

Why create a full_name method instead of formatting strings outside the class?

Formatting full names outside the class requires repeating the same logic every time a full name is needed. A full_name method centralizes the behavior inside the class and returns the computed string using self.first and self.last, making it reusable across all instances.

Review Questions

  1. When you create employee1 = Employee('Corey','Schaefer',50000), what arguments does __init__ receive, and which one is automatically supplied?
  2. What error occurs if a method like full_name is defined without the self parameter, and why does it happen?
  3. How does calling Employee.full_name(employee1) differ from calling employee1.full_name() in terms of how self is provided?

Key Points

  1. 1

    Classes act as blueprints, while instances are the individual objects created from those blueprints.

  2. 2

    Instance variables store data unique to each object, such as first name, last name, email, and pay for each employee.

  3. 3

    The __init__ method runs automatically during instance creation and is the standard place to set instance variables.

  4. 4

    Methods encapsulate behavior; full_name returns a computed value using instance data instead of duplicating formatting code.

  5. 5

    The self parameter is required because Python automatically passes the instance to instance methods.

  6. 6

    Calling a method on an instance supplies self automatically; calling the same method on the class requires passing the instance explicitly.

Highlights

The __init__ method eliminates repetitive attribute assignments by running automatically whenever a new instance is created.
For instance methods, self is not optional: omitting it triggers a TypeError because Python still passes the instance.
employee1.full_name() and Employee.full_name(employee1) do the same work, but only the instance call supplies self automatically.
Instance variables are the mechanism for per-object data; class-level structure alone isn’t enough to store unique values per employee.

Topics

Mentioned