Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 16

Initializing Object Attributes with `__init__`

Recommended resources

Hello! Welcome to the third lesson in our module on Object-Oriented Programming.

In our last lesson, we learned how to define a basic class using the class keyword. We created a Dog class with a bark method, but we ran into a limitation: every Dog object we created was identical. We had no way to give each dog a unique name or age.

Today, we'll solve that problem. Your goal is to implement a constructor (__init__) to initialize object attributes. This special method is the key to creating objects that have their own unique data from the moment they are born.


1. The Problem: Setting Data Manually

Imagine you want to represent employees in a program. Each employee has a name, email, and salary. Without a constructor, you'd have to create an empty object first and then set its data step-by-step.

This short video clip demonstrates how tedious and error-prone this manual process is.

Python OOP Tutorial 1: Classes and Instances

Watch this clip from Corey Schafer's 'Python OOP Tutorial' to see the 'hard way' of assigning data to objects. Notice how easy it is to make a mistake.

Watch from 03:08 to 05:03. The narrator manually creates attributes for two Employee instances. Pay attention to the mistake he makes and how much code it requires. This will motivate why we need a better method.

As you can see, the manual approach is clunky. We need a way to ensure that every Employee object is created with all its necessary information, automatically.


2. The Solution: The __init__ Constructor

Python's solution is a special method named __init__. This method is called a constructor because it runs automatically every time you create a new instance of a class. Its job is to set up the object's initial state.

The name __init__ is short for "initialize." Methods that start and end with double underscores are often called "dunder" methods in Python, and they have special meaning.

Let's watch the next part of the same video to see how __init__ works.

Python OOP Tutorial 1: Classes and Instances

Now, let's see the proper solution. This clip introduces the __init__ method and explains its syntax.

Watch from 05:03 to 07:09. Focus on these key points: The syntax: def __init__(self, first, last, pay): The self parameter: It automatically receives the instance being created. Attribute assignment: The code self.first = first attaches the first parameter to the object as an attribute.

To reinforce what you just saw, let's look at a clear written explanation.

Object-Oriented Programming (OOP) in Python

The article 'Object-Oriented Programming (OOP) in Python' on Real Python provides an excellent breakdown of the __init__ method. Reading this will help solidify your understanding.

In the article, find the sub-heading 'Class Definition' and read the paragraphs that describe the __init__ method. Start from 'You define the properties that all Dog objects must have...' and stop just before the part about 'class attributes'.


3. Understanding self and Attribute Assignment

The most important and sometimes confusing part of the __init__ method is the line self.name = name. Let's break this down carefully.

  • self: A reference to the current object being created. Think of it as the object referring to itself. When you create employee1, self is employee1. When you create employee2, self is employee2.
  • name (on the right side): This is the parameter—the value that was passed into the constructor (e.g., the string "Corey").
  • self.name (on the left side): This creates an instance attribute. It attaches the value from the name parameter to the self object, storing it for later use.

This article uses a great analogy to explain this.

Python OOP for Absolute Beginners: What Are Classes ... - Medium

This article from Medium, 'Python OOP for Absolute Beginners', provides a very intuitive way to think about self and attribute assignment.

Read the sections titled 'So… What Is self?' and 'Why self.name = name?'. The analogy of a sticky note is particularly helpful for understanding how data gets stored in an object.


4. Putting It All Together

Now that we have an __init__ method, creating a new Employee object is much cleaner. We simply pass the required arguments when we instantiate the class.




# Before (manual and error-prone)
# emp_1 = Employee()
# emp_1.first = 'Corey'
# emp_1.last = 'Schafer'
# emp_1.pay = 50000




# After (clean, automatic, and safe)
emp_1 = Employee('Corey', 'Schafer', 50000)

Let's watch the final part of the video clip, which demonstrates this exact improvement.

Python OOP Tutorial 1: Classes and Instances

This clip shows how using the __init__ method streamlines object creation and makes the code much more readable and robust.

Watch from 07:09 to 08:54. The video shows how to create the Employee instances by passing arguments directly to the class. Notice how much code this eliminates compared to the manual method from the first clip.

Here is an image showing another complete example with a Parrot class. It neatly summarizes the entire process: defining the class with __init__, creating instances with unique data, and accessing that data.

Python Constructor Example
This image shows a `Parrot` class being defined with an `__init__` method to set the `name` and `age` for each parrot. Two different `Parrot` objects are then created, and their unique attributes are printed.

5. Practice: Build a Car Class

It's time to write your own class with a constructor. This exercise will cement what you've learned.

Your Task:

  1. Open your code editor.
  2. Define a new class named Car.
  3. Implement the __init__ method for the Car class. It should accept two arguments (in addition to self):
    • color (a string)
    • mileage (an integer)
  4. Inside __init__, create two instance attributes: self.color and self.mileage, and assign the parameter values to them.
  5. Create two Car objects:
    • A blue car with 20,000 miles.
    • A red car with 30,000 miles.
  6. Print the color and mileage of each car. The output should look like this:
    The blue car has 20000 miles.
    The red car has 30000 miles.
    
Click here to see a possible solution after you've tried it yourself.



# 1. Define the Car class
class Car:



    # 2. Implement the __init__ method
    def __init__(self, color, mileage):



        # 3. Create instance attributes
        self.color = color
        self.mileage = mileage




# 4. Create two Car objects (instances)
blue_car = Car("blue", 20000)
red_car = Car("red", 30000)




# 5. Print the attributes of each car
print(f"The {blue_car.color} car has {blue_car.mileage} miles.")
print(f"The {red_car.color} car has {red_car.mileage} miles.")


Conclusion

Excellent work! You've just learned one of the most fundamental concepts in object-oriented programming. By using the __init__ constructor, you can now create robust blueprints for objects that are initialized with their own unique state.

Key Takeaways:

  • The __init__ method is a special constructor that runs automatically when you create a new object.
  • The first parameter of __init__ is always self, which refers to the instance being created.
  • You pass arguments to the constructor when you instantiate the class, like my_car = Car("blue", 20000).
  • Inside __init__, you use self.attribute = value to store data on the object as an instance attribute.

So far, our objects have data (attributes). But what can they do with that data? In the next lesson, we will learn how to define and call methods on an object that can access and work with its unique attributes.